Python基本特殊方法之__new__
__new__()和不可变对象
__new__方法的一个用途是初始化不可变对象,__new()__方法中允许创建未初始化的对象,这允许我们在__init__()方法被调用之前先设置对象的属性
例:为float对象定义一个包含单位信息的属性
(1)重载__init__()方法
#coding = utf-8 class myfloat(float): def __init__(self, value, unit): self.value = value self.unit = unit if __name__ == "__main__": f = myfloat(3, "hello")
说明对于内置的float类不能简单的重载__init__()方法,对于其他的内置不可变类型也是同样的问题,我们不能在不可变对象self上设置新的属性值
(2)重载__new__()方法
#coding = utf-8 class myfloat(float): def __new__(cls, value, unit): obj = super().__new__(cls, value) #obj.unit = unit return obj def __init__(self, value, unit): self.value = value self.unit = unit if __name__ == "__main__": f = myfloat(3, "kg") print (f.value, f.unit) print (f, f.unit)
__new__()和元类型
例:实现有序属性
#coding=utf-8 class myclass(type): @classmethod def __prepare__(mcs, name, bases, **kwargs): return super().__prepare__(name,bases,**kwargs) def __new__(cls, name, bases, namespace, **kwargs): print ("name:",name) print ("bases:",bases) print ("namespace:",namespace) a = super().__new__(cls, name, bases, namespace) a._order = tuple(c for c in namespace if not c.startswith("__")) print (a) print (type(a)) return a def __init__(self, name, bases,namespace, **kwargs): super().__init__(name, bases, namespace) class people(metaclass=myclass): name = "zhanglin" age = "31" def sayhello(self): self.color="red" print ("say hello") if __name__ == "__main__": p = people() print (p._order)