在python中像__init__这类双下划线开头和结尾的方法,统称为魔术方法
1、__init__ :在创建对象的时候,自动调用对 创建的对象 进行初始化设置的
2、__new__:如果要控制类里面对象创建的过程,可以通过自定义new方法去实现
class MyClass(object): def __init__(self): """初始化方法""" print("---init---方法") def __new__(cls, *args, **kwargs): print("--new方法---") return super().__new__(cls) if __name__ == '__main__': m = MyClass() print(m) """ --new方法--- ---init---方法 <__main__.MyClass object at 0x0000018D229225E0> """
单例模式的实现(__new__)
class Demo: __instance=None def __new__(cls, *args, **kwargs): if cls.__instance is None: cls.__instance=super().__new__(cls) return cls.__instance if __name__=="__main__": d1=Demo() d2=Demo() print(id(d1),id(d2))
上下文管理器:是一个python对象,为操作提供了额外的上下文信息。这种额外的信息,在with 语句初始化上下文,以及完成with块中的所有代码时,采用可调用 的形式。
object.__enter__(self) 输入与此对象相关的运行是上下文。如果存在的话,with语句将绑定该方法的返回值到该语句的as子语句中指定目标。
object.__exit__(self, exc_type, exc_val, exc_tb)
exc_type: with中的代码如果执行出错,则会将异常类型传递给exc_type
exc_val: with中的代码如果执行出错,则会将异常信息传递给exc_val
exc_tb: with中的代码如果执行出错,则会将异常溯源对象传递给exc_tb
退出与此对象相关的欲仙时上下文。参数描述导致上下文退出的异常。如果该上下文退出时没有异常,3个参数都将为None。
如果提供了一个异常,并且该方法希望抑制该异常,它应该返回一个真值;否则在退出该方法后,异常将被正常处理。
上下文管理器的实现: 如果在一个类中实现了 __enter__,__exit__ 这2个方法,那么这个类就当做一个上下文管理器
with是用来启动对象的上下文管理器的
应用场景:涉及所有需要执行关闭的操作,在封装的时候可以去实现它的上下文协议 (例如:数据库的连接)
class OpenFile(object): '''手动实现文件操作的上下文''' def __init__(self, filename, method): # 初始化打开文件 self.file = open(filename, method) def __enter__(self): # 启动上下文时,将打开的对象返回出去 return self.file def __exit__(self, exc_type, exc_val, exc_tb): # 退出上下文时,将文件关闭 self.file.close() if __name__ == '__main__': ff = OpenFile('python.txt', 'w') with ff as f: f.write('hello')
__call__: 实现类的对象 调用的行为
class Demo: def __call__(self, *args, **kwargs): print("__demo___") def func(): print("____func") if __name__=="__main__": c=Demo() print(callable(func)) print(callable(c)) func() c() """ True True ____func __demo___ """
类实现装饰器
class Demo: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print("---装饰器扩展的代码-start--") self.func() print("---装饰器扩展的代码-end--") @Demo # func = Demo(func) def func(): """注释""" print('----func---') """ ---装饰器扩展的代码-start-- ----func--- ---装饰器扩展的代码-end-- """