Python 入门 之 双下方法

1、双下方法

​ 定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码。

(1)调用:不同的双下方法有不同的触发方式,

<1> __ len__ -- len() 触发

class A(object):

    def __init__(self,name):
self.name = name
print("触发了__init__") def __len__(self): # len() 触发
print("走这里")
return len(self.name) # return len("xqrqwr") str中__len__
# 必须有返回值,返回值的类型必须是整型 a = A("xqrqwr")
print(len(a)) # str
a = "12345" # str这个类的实例
lst = [1,2,3,4,4,5,5,5,5] # list这个类的实例
print(len(a))
print(len(lst))

<2> __ hash__ --hash() 触发

class A(object):

    def __init__(self,name,age):
self.name = name
self.age = age def __hash__(self): # hash()
hash({1,2,345}) # 可变数据类,不可数据类型
return 1
# 必须有返回值,返回值的类型必须是整型 a = A("meet",25)
print(hash(a))

<3> __ str__ --print 或者 str() 触发

class A:

    def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex def __str__(self): # print 触发 str()
print(111)
return f"姓名:{self.name} 年龄:{self.age} 性别:{self.sex}"
# 必须有返回值,返回值的类型必须是字符串 a = A("mee",20,"男")
a1 = A("mee1",200,"男1")
str(a)
print(a)
print(a1) # 以下对比:
a = A("mee",20,"男")
a1 = A("mee2",200,"女") print(f"姓名:{a.name} 年龄:{a.age} 性别:{a.sex}") # "姓名:meet 年龄:20 性别:男"
print(f"姓名:{a1.name} 年龄:{a1.age} 性别:{a1.sex}") # "姓名:meet2 年龄:200 性别:女"

<4> __ repr__ --print 或者 %r 触发

class A:

    def __init__(self):
pass def __repr__(self): # print触发 %r
print(1111)
return "天魔" def __str__(self): # str 优先级高于 repr 两个都存在就只执行str
return "小元" a = A()
print("%r"%(a))

<5> __ call__ --对象调用时触发,对象后加括号即:对象() 或者 类()()

class A:

    def __init__(self):
pass def __call__(self, *args, **kwargs): # 对象()时调用的__call__
print("走我")
print(*args, **kwargs) a = A()
a()

<6> __ eq__ 等于

class A(object):

    def __init__(self,name,age):
self.name = name
self.age = age def __eq__(self, other): # a == a1
if self.name == other.name:
return True
else:
return False a = A("mee",56)
a1 = A("mee",108) print(a == a1)

<7> __ del__ 构造方法,当对象在内存中被释放时,自动触发执行

​ 此方法一般情况下无需定义,因为python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为内存的分配和释放都是交给python解释器类执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class A:
def __init__(self):
pass def __del__(self): del 触发
print("删除时执行我") a = A() import time
time.sleep(5)
del a a = 1
b = a
a = b
垃圾回收机制:
# 80 5/s
# 引用计数
# 标记清除
# 分袋回收 袋一:10 2/h 袋二: 5/3 4h 袋三: 3 20h

<8> __ item__ 系列 可以像操作字典一样操作实例方法

dic["键"] = 值
del dic["键"]
dic["键"]
class A:

    def __init__(self,name,age):
self.name = name
self.age = age def __getitem__(self, item):
print(self.__dict__)
print(self.__dict__[item]) # self.__dict__ 获取的就是字典 def __setitem__(self, key, value):
self.__dict__[key] = value def __delitem__(self, key):
del self.__dict__[key] a = A("meet",58)
a["sex"] = "男"
a["sex"]
del a["sex"]
print(a.__dict__)

<9> __ new__ 单例模式(工厂模式)

​ 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

class A(object):

    def __init__(self,name):  # 初始化
self.name = name
print("我是__init__,先走我") def __new__(cls, *args, **kwargs):
print("我是__new__,先走我")
return "啦啦啦" a = A("meet")
print("我是谁:",a)
class A(object):

    def __init__(self,name):  # 初始化
self.name = name
print("我是__init__,先走我") def __new__(cls, *args, **kwargs):
obj = object.__new__(A)
print("我在哪:",obj)
return obj # obj == __init__() a = A("meet")
print("我是谁:",a)
class A(object):

    def __init__(self,name): # 初识化
self.name = name def __new__(cls, *args, **kwargs):
obj = object.__new__(A) # 调用的是object类中的__new__ ,只有object类中的__new__能够创建空间
return obj #本质: obj == __init__() return __init__() # 触发了__init__方法 a = A("mee") # a是对象的内存地址
a1 = A("天魔") # a是对象的内存地址
a2 = A("天阳") # a是对象的内存地址
print(a.name)
print(a1.name)
print(a2.name)
# 先执行__new__方法再执行__init__方法

class A:
__a = None #__a = 0x000001F346079FD0 def __init__(self,name,age):
self.name = name
self.age = age def __new__(cls, *args, **kwargs):
if cls.__a is None:
obj = object.__new__(cls)
cls.__a = obj
return cls.__a a = A("mee",123) # 地址0x000001F346079FD0
a1 = A("天魔",11)
print(a.name)
print(a1.name)
单例模式:不管创建多少次,使用的都是同一个内存空间
模块的导入,手写的单例模式
实例化对象时发生的事:
创建对象,并开辟对象空间 __ next__
自动执行 __ init方法,隐性的将对象地址传给self
将对象属性封装到对象空间

2、上下文

(1)__ enter__

(2)__ exit__

class my_open:

    def __init__(self,file,mode="r",encoding="utf-8"):
self.file = file
self.mode = mode
self.encoding = encoding def __enter__(self):
self.f = open(self.file,self.mode,encoding=self.encoding)
return self.f def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type,exc_val,exc_tb) # 没有错误时就是None
self.f.close() with my_open("a.txt") as ffff:
for i in ffff:
print(i)
print(ffff.read(1111))
print(ffff.read())

Python 入门 之 双下方法的更多相关文章

  1. python之路-双下方法

    双下方法 定义: 双下方法是特殊方法,他是解释器提供的,由双下线加方法名加双下划线 __方法名__具有特殊意义的方法 双下方法主要是Python源码程序员使用的,元编程 我们在开发中尽量不要使用双下方 ...

  2. 百万年薪python之路 -- 面向对象之 反射,双下方法

    面向对象之 反射,双下方法 1. 反射 计算机科学领域主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性.python ...

  3. Python面向对象 | 双下方法

    定义:双下方法是特殊方法,他是解释器提供的.由双下划线+方法名+双下划线 .它具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更 ...

  4. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  5. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  6. Python面向对象之反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  7. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  8. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  9. python之面向对象函数与方法,反射,双下方法

    一.函数和方法 1.函数和方法的区别 函数: 全都是显性传参,手动传参,与对象无关 方法: 存在隐性传参,与对象有关 1.1通过函数名可以判断 len()就是函数 str.count()就是方法 de ...

随机推荐

  1. 为什么还需要学习TypeScript

    开篇 TypeScript 是由 C#语言的创始人 Anders Hejlsberg 设计的一种编程语言,设计的初衷就是为了帮助 JavaScript 的开发人员能像类似高级语言c#,Java那样编写 ...

  2. C++中void和void*指针的含义 (指针类型的含义)

    转载自:http://blog.csdn.net/lee_shuai 指针有两个属性:指向变量/对象的地址和长度,但是指针只存储地址,长度则取决于指针的类型:编译器根据指针的类型从指针指向的地址向后寻 ...

  3. 批量修改谷歌浏览器(Chrome)地址栏保存的历史记录及导出功能探索研究

    内网IP调整引发的Chrome历史记录修改及ShadowRoot的学习 由于IP经常变动, 导致本地项目的那些存在地址栏的历史记录就都失效了, 突然脑洞大开, 有没有办法修改本地历史记录的方法? 想法 ...

  4. Maximum upload size exceede上传文件大小超出解决

    在这里记录三种方法, 努力提高自己的姿势水平 application.yml配置 spring: servlet: multipart: enabled: true max-file-size: 10 ...

  5. pl/sql 过程 函数(写一个过程,输入部门编号,在控制台打印这个部门的名称,总人数,平均工资(基本工资+奖金))

    1.编写过程,输入三角形三个表的长度.在控制台打印三角形的面积. create or replace procedure pro_s(v_a number,v_b number,v_c number) ...

  6. TCP输入 之 快速路径和慢速路径

    概述 快速路径:用于处理预期的,理想情况下的数据段,在这种情况下,不会对一些边缘情形进行检测,进而达到快速处理的目的: 慢速路径:用于处理那些非预期的,非理想情况下的数据段,即不满足快速路径的情况下数 ...

  7. Linux常用指令grep(搜索过滤)

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...

  8. Python中的OS对路径的操作以及应用

    目录处理 OS目录处理目录-->路径,文件夹 文件:html 1. 新建和删除一个目录import os #引入os目录from xx import xxos.mkdir("D:\\P ...

  9. centos6一键安装WordPress

    #!/bin/bash service iptables stop setenforce yum -y install httpd service httpd restart yum -y insta ...

  10. koa 项目实战(三)创建测试接口和用户模型

    1.创建测试接口,并引入用户模型 根目录/routes/api/users.js const Router = require('koa-router'); const router = new Ro ...