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())

最新文章

  1. nandflash驱动程序编写
  2. Repeater、地址栏传值、Response--2016年12月30日
  3. initWithCoder与initWithFrame的区别
  4. C生成随机数,奇葩问题
  5. JS获取form表单的所有输入值
  6. Java利用aspose-words将word文档转换成pdf(破解 无水印)
  7. swift如何动态创建对象
  8. Oracle自定义函数实例
  9. 用crontab、crond在嵌入式系统中添加定时任务
  10. 发送trim值
  11. 第一百二十八节,JavaScript,Ajax
  12. APP生产流程图片解说
  13. unity Editor的使用
  14. MAC 下虚拟主机的配置
  15. Java的深拷贝和浅拷贝
  16. python五十五课——calendar模块
  17. Tomcat启动报错:org.apache.catalina.LifecycleException: Failed to start component...java.util.zip.ZipException: error in opening zip file
  18. (动态规划 01背包 打印路径) CD --UVA --624
  19. java中删除list指定元素遇到的问题
  20. hdu1226 超级密码 (BFS,里面用了大数取余原理)

热门文章

  1. Python3学习笔记(十八):文件上传和下载
  2. 「Luogu P5601」小D与笔试
  3. LightGBM GPU python版本安装
  4. springboot拦截异常信息发送邮件提醒
  5. koa 基础(十六)koa 中 session 的使用
  6. NullPointerException 没有堆栈
  7. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
  8. Cortex-M3 异常返回值EXC_RETURN
  9. OGG-01201
  10. Android中图片的三级缓存