1.上下文管理器
2.模式方法
1.上下文管理器
1).python的上下文管理协议:包含__enter__() 、__exit__()
2)上下文管理器:支持"上下文管理的协议"的对象(同时支持__enter__()、__exit__())
3)with 语句操作上下文管理器对象
with object as o:
pass
? with后的object是上下文管理器的对象;o是__enter__()的返回值
举例:在执行with里的语句之前,先执行__enter__(),再执行with中的语句,最后执行__exit__()-------即上下文管理器
""" python上下文管理的协议:包含__enter__() 、__exit__() 上下文管理协议:支持"上下文管理的协议"的对象(同时支持__enter__()、__exit__()) with 后面跟的是上下文管理器的对象 """ # 自定义上下文管理器---包含__enter__()、__exit__() class MyClass(object): def __enter__(self): print("enter is running...") def __exit__(self, exc_type, exc_val, exc_tb): print("exit is running...") def main(): # 实例对象 obj = MyClass() with obj as o: print("with is running...") if __name__ == ‘__main__‘: main() """ enter is running... with is running... exit is running... """
4)常见的上下文管理器
open(file)
with open("上下文管理器.txt","w",encoding="utf8") as f: f.write("python")
为什么open能够被with操作?看看open()的返回值包含哪些属性:
f = open("上下文管理器.txt") # f就是一个上下文管理器 print(dir(f)) """ ... ,‘__enter__‘, ‘__eq__‘, ‘__exit__‘, ... """
open()的返回值f是一个上下文管理器,所以可以被with操作。
当然,不是上下文管理器,是不能被with操作的!如下:
with 1 as o: pass """ with 1 as o: AttributeError: __enter__ """
5)如果一个对象不是上下文管理器,怎么变成上下文管理器
在继承的新的类中,添加__enter__() 、__exit__() 2个方法即可。
# 一个对象不是上下文管理器,怎么变成上下文管理器: 继承,在新的类中添加2个方法 class Base(object): pass class MyBase(Base): def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): pass
2.魔术方法:
在python中方法名如果是__xxxx__()
的,那么就有特殊的功能,因此叫做“魔法”方法
1)__str__:
__str__(self)
方法,那么就会打印这个方法中return的数据__str__
方法需要返回一个字符串,当做这个对象的描写举例,不写__str__()方法(默认继承object的str方法,返回的是存储地址)
class MyClass(object): def __init__(self,name): self.name = name def main(): a = MyClass("zhangsan") print(a) if __name__ == ‘__main__‘: main() # <__main__.MyClass object at 0x000001B57D0BEC88>
重写__str__()
class MyClass(object): def __init__(self,name): self.name = name def __str__(self): print("这是对对象的描述...") return self.name def main(): a = MyClass("zhangsan") print(a) if __name__ == ‘__main__‘: main() """ 这是对对象的描述... zhangsan """
2).让自定义的类生成的对象(实例)能够使用运算符进行操作
首先来看下list的相加:
def main(): a = [1, 2, 3] b = [4, 5, 6] return a + b if __name__ == ‘__main__‘: print(main()) # [1, 2, 3, 4, 5, 6]
为什么list能够相加?因为list含有__add__属性
def main(): a = [1, 2, 3] b = [4, 5, 6] print(hasattr(a,"__add__")) # True return a + b if __name__ == ‘__main__‘: print(main())
1)对象没有__add__属性,进行相加:报错
class MyClass(object): pass def main(): a = MyClass() b = MyClass() return a + b if __name__ == ‘__main__‘: print(main()) # TypeError: unsupported operand type(s) for +: ‘MyClass‘ and ‘MyClass‘
对象添加__add__属性
两个对象能不能相加,取决于该对象有没有__add__属性
class MyClass(object): def __init__(self, value): self.value = value def __add__(self, other): return self.value + other.value # self 是a对象,other是b对象 def main(): a = MyClass(11) b = MyClass(23) return a + b if __name__ == ‘__main__‘: print(main()) # 34
3)__del__:Python解释器释放实例对象,调用该方法------析构方法
当删除一个对象时,Python解释器也会默认调用一个方法,这个方法为__del__()方法。在Python中,对于开发者来说很少会直接销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份工作。也就是说,不管是手动调用del还是由Python自动回收都会触发__del__方法执行。
①创建多个对象的时候触发__del__方法,python解释器自动删除对象,释放内存
# python解释器删除不再用的对象 ,释放内存 class MyClass(object): def __init__(self): print("init is running...") def __new__(cls, *args, **kwargs): print("new is running...") instance = super().__new__(cls) return instance def __del__(self): print("del is running...") def main(): a = MyClass() b = MyClass() if __name__ == ‘__main__‘: main() print("main() is running...") """ new is running... init is running... new is running... init is running... del is running... del is running... main() is running... """
②del关键字手动删除
当使用del 把内存的所有应用删除,立刻调用__del__方法
class MyClass(object): def __init__(self): print("init is running...") def __new__(cls, *args, **kwargs):
#创建对象 分配内存 print("new is running...") instance = super().__new__(cls) return instance def __del__(self):
#销毁对象 print("del is running...") def main(): a = MyClass() b = MyClass() del a del b
__del__用其他应用场景:在对象被销毁前,进行一些其他操作。
4)多态 (面向对象的三大特征:封装、继承、多态)
类型动态
同样的方法,根据不同的对象,会有不同的行为结果。
# 多态 class MyClass(object): def music(self): print("myclsss music is running...") class AClass(MyClass): def music(self): print("Aclass music is running...") class BClass(MyClass): def music(self): print("Bclass music is running...") def func(obj): obj.music() # 只要这个对象有music方法,就会正常调用 if __name__ == ‘__main__‘: m = MyClass() a = AClass() b = BClass()
#上面三个对象都有music方法,都可以正常调用该方法 func(a) func(b) func(m) """ Aclass music is running... Bclass music is running... myclsss music is running... """
原文:https://www.cnblogs.com/ananmy/p/14094973.html