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__()方法

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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__()和元类型

例:实现有序属性

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sinat_38682860/article/details/120186542