Python中用于对对象进行的一些控制和通用处理 是通过魔术方法来实现
什么是魔术方法 通过__function_name__ 来定义魔术方法,但是需要注意通常的魔术方法是python预置的,所以function_name通常是python中定义过的魔术方法名。
Python的魔术方法如果没有在类中进行定义,则是被隐式定义的(或者说由基类继承而来)
如最常见的__init__ 也是一个魔术方法。它发生在Python实例的构建阶段,通过__init__ 来完成对类定义属性的初始赋值 :
1 2 3 4 class person : def __init__ (self,name ) : self .name = name
这样 name就从一个局部变量成为一个person实例的实例属性
“__new__” 不太常用,但在进行类设计过程中用到的__new__ 也是一个魔术方法,它发生在初始化之前,用于向堆中申请内存,以及对实例的创建过程进行控制,返回的是类的实例(将创建的内存空间返回),最常见的是单例模式的定义 :
1 2 3 4 5 6 7 8 class knife : _instance = None def __new__ (cls, *args, **kwargs ): if cls._instance is None : cls._instance = super (knife, cls).__new__(cls) return cls._instance
“__str__” “__str__” 用于重写对象的字符串打印
1 2 3 4 5 6 7 class person : def __init__ (self,name ): self .name = name def __str__ (self ): return self .name print (person("wang" ))
“__eq__” “__eq__”等一些魔术方法,用于重新定义运算处理的逻辑
1 2 3 4 5 6 7 8 9 10 class person : def __init__ (self,name,age ): self .name = name self .age = age def __eq__ (self, value ): return self .age==value.age c = person("wang" ,26 ) d = person("zhao" ,26 )print (c == d )
“__len__” 还有一些魔术方法用于处理一些内置函数的调用,当某些内置函数被调用时,实际调用的这些魔术方法
1 2 3 4 5 6 7 8 9 class person : def __init__ (self,name,age ): self .name = name self .age = age def __len__ (self ): return 0 np = person("zhao" ,"27" )print (len (np))
“enter “ / “ __exit__” “enter ”/ “__exit__” 主要在使用with语句 时的会触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class MyResource : def __enter__ (self ): print ("打开资源" ) return self def __exit__ (self, exc_type, exc_val, exc_tb ): print ("释放资源" )with MyResource() as r: print ("处理中..." )
“__call__” “call__” 方法允许对象创建的实例变为可调用的,即允许向实例传入参数,使实例也可以进行一些功能的处理。__call 和 函数在传入参数执行的行为上是一致的,但是在调用和查询方面的具体实现不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class button : def __init__ (self,status=False ): self .status = status def __call__ (self ): if self .status : self .status = False print ("the light is closed" ) else : self .status =True print ("the light is on" ) light_button =button() light_button() light_button()