python魔法函数是什么,python中的魔术方法
1、什么是魔法方法?
魔法是一种特殊的方法,可以给你的类添加魔法。如果您的对象实现(重载)了这些方法中的一个,那么Python将在特殊情况下调用该方法。你可以定义你想要的行为,所有这些都是自动触发的。它们通常由两个下划线命名(如__init__,__lt__)。Python的魔法非常强大,所以知道如何使用尤为重要!
2、__init__(self[, ...]),__new__(cls[, ...]),__del__(self)
(1)__init__构造函数,创建实例时初始化的方法。但它不是实例化调用的第一个方法。__new__是实例化该对象的第一个方法。它只接受cls参数,并将其他参数传递给__init__。__new__很少使用,但是有适合它的场景,特别是当一个类继承自不经常改变的类型时,例如元组或字符串。
(2)使用_ _ new _ _时注意以下四点:
a,__new__是对象实例化时调用的第一个方法;
b,它的第一个参数是这个类,其他参数用来直接传递给__init__方法;
c,__new__返回一个构建的实例;
d、__new__决定是否使用__init__方法,因为__new__可以调用其他类的构造函数或者直接返回其他实例对象作为这个类的实例。如果__new__不返回实例对象,将不会调用_ _ init _ _
e、__new__主要用于继承元组或字符串等不可变类型。
相关:《Python平台》
__new__实现单例模式(无论多少次实例化,结果都是同一个实例)
Singleton模式是一种常见的软件设计模式,其主要目的是确保某个类只存在一个实例。当您希望一个类只有一个实例出现在整个系统中时,单例对象可以派上用场。
例如,服务器程序的配置信息存储在一个文件中,客户端通过AppConfig类读取配置文件的信息。如果在程序运行过程中需要在很多地方使用配置文件的内容,也就是说需要在很多地方创建AppConfig对象的实例,这就会导致系统中出现多个AppConfig对象的实例,而这样会严重浪费内存资源,尤其是当配置文件的内容很多的时候。事实上,对于AppConfig这样的类,我们希望在程序运行期间只存在一个实例对象。
示例:
classPerson(object):
def__init__(自己,姓名,年龄):
self.name=name
年龄=年龄
def__new__(cls,*args,**kwargs):
ifnothasattr(cls, instance):
cls.instance=super()。__新__(cls)
returncls.instance
a=人( p1 ,21)
b=人( p2 ,22)
Print(a==b,a.name==b.name)#这里打印出来的结果都是真的,所以可以看出A和B都是同一个实例(实例B覆盖了实例A)。
#单一示例函数:
#一是控制资源的使用,通过线程同步控制资源的并发访问;
#二、控制实例数量,达到节约资源的目的;
#第三,作为交流媒介,即数据共享。比如数据库连接池的设计一般采用singleton模式,数据库连接是数据库资源的一种。
#应用场景:
#Python的logger是用于日志记录的单例模式。
n
bsp;#线程池、数据库连接池等资源池一般也用单例模式
#Windows的资源管理器是一个单例模式
#网站计数器(3)__del__ 析构器,当实例被销毁时调用。
3、__call__(self[,args ...]),__getitem__(self,key),__setitem__(self,key,value)
(1)__call__ 允许一个类的实例像函数一样被调用,如下:
classPerson(object):(2)__getitem__ 定义获取容器中指定元素的行为,相当于self[key],如下:def__init__(self,name,age):
self.name=name
self.age=age
self.instance=add
def__call__(self,*args):
returnself.instance(*args)
defadd(args):
returnargs[0]+args[1]
a=Person('p1',20)
print(a([1,2]))
#这里将打印3
#可见当创建a这个对象之后,如果定义了__call__函数则对象是可以像函数一样调用的。
classPerson(object):(3)__setitem__ 设置容器中指定元素的行为,相当于self[key] = value 。def__init__(self,name,age):
self.name=name
self.age=age
self._registry={
'name':name,
'age':age
}
def__call__(self,*args):
returnself.instance(*args)
def__getitem__(self,key):
ifkeynotinself._registry.keys():
raiseException('Pleaseregistrythekey:%sfirst!'%(key,))
returnself._registry[key]
a=Person('p1',20)
print(a['name'],a['age'])
#这里打印的是'p1'20
#可见__getitem__使实例可以像字典一样访问
4、__getattr__(self,name),__getattribute__(self,name),__setattr__(self,name,value),__delattr__(self,name)
(1)__getattr__ ():当用户试图访问一个不存在属性时触发;
(2)__getattribute__(): 当一个属性(无论存在与否)被访问时触发;
(3)__setattr__ ():当一个属性被设置时触发;
(4)__delattr__ ():当一个属性被删除时触发。
classPerson(object):def__init__(self,name,age):
self.name=name
self.age=age
self._registry={
'name':name,
'age':age
}
def__getattribute__(self,item):
#注意此处不要再访问属性,如self.__dict__[item]
#因为self.__dict__依然会被__getattribute__拦截,这样就会陷入死循环
returnobject.__getattribute__(self,item)
def__getattr__(self,item):
print("don'thavetheattribute",item)
returnFalse
def__setattr__(self,key,value):
self.__dict__[key]=value
a=Person('p1',20)
print(a.cs)#这里会打印don'thavetheattributecs以及False
a.cs='测试'#这里设置该属性值为'测试'
print(a.cs)#这里将打印出'测试'
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。