Python中用于对对象进行的一些控制和通用处理 是通过魔术方法来实现
什么是魔术方法通过__function_name__ 来定义魔术方法,但是需要注意通常的魔术方法是python预置的,所以function_name通常是python中定义过的魔术方法名。
Python的魔术方法如果没有在类中进行定义,则是被隐式定义的(或者说由基类继承而来)
如最常见的__init__ 也是一个魔术方法。它发生在Python实例的构建阶段,通过__init__ 来完成对类定义属性的初始赋值 :
1234#定义一个 类的初始化方法class person : def __init__(self,name) : self.name = name
这样 name就从一个局部变量成为一个person实例的实例属性
“__new__”不太常用,但在进行类设计过程中用到的__new__ 也是一个魔术方法,它发生在初始化之前,用于向堆中申请内存,以及对实例的创建过程进行控制,返回的是类的实例(将创建的内存空间返回),最常见的是单例模式的定义 :
12345678class 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__” 用于重写对象的字符串打印
1234567class person : def __init__(self,name): self.name = name def __str__(self): return self.name # 将打印字符定义为self.name,不然则返回person对象的内存地址print(person("wang"))
“__eq__”“__eq__”等一些魔术方法,用于重新定义运算处理的逻辑
12345678910class person : def __init__(self,name,age): self.name = name self.age = age def __eq__(self, value): return self.age==value.agec = person("wang",26)d = person("zhao",26)print(c == d )
“__len__”还有一些魔术方法用于处理一些内置函数的调用,当某些内置函数被调用时,实际调用的这些魔术方法
123456789class person : def __init__(self,name,age): self.name = name self.age = age def __len__(self): return 0np = person("zhao","27")print(len(np)) #重新定义了__len__ ,会根据方法的返回值返回,这里打印0
“enter “ / “ __exit__”“enter ”/ “__exit__” 主要在使用with语句 时的会触发
1234567891011121314class 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 和 函数在传入参数执行的行为上是一致的,但是在调用和查询方面的具体实现不同
123456789101112131415161718class 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() # 创建button 实例light_button() # 执行实例 status : False -> Truelight_button() # 执行实例 status : True -> False# 输出# the light is on# the light is closed