不通过调用__Init__来创建实例

老样子,抛出个问题,我们想要创建一个实例,但是由于某些原因想绕过__init__方法,用别的方式来进行创建。

举个栗子

小贱贱反序列化数据,或者说实现一个类方法将其作为备选的构造函数,都属于这种情况。举个栗子:

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

采用下面的方法可以不用调用__init__()创建一个Date实例:

d = Date.__new__(Date)

但是注意,此时使用d.year就会给你报个错

因为得到的实例是未经初始化的,因此给实例变量设定合适的初始值现在就成了我们的责任。

ok……在下面的例子中给出:

from time import localtime

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    @classmethod
    def today(cls):
        d = cls.__new__(cls)
        t = localtime()
        t.year = t.tm_year
        t.month = t.tm_mon
        t.day = t.tm_mday
        return d

类似的,假如正在反序列化JSON数据,要产生下面酱紫的字典:

要产生类似字典的数据咋搞呢?

from time import localtime

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    @classmethod
    def today(cls):
        d = cls.__new__(cls)
        t = localtime()
        T = {}
        T['year'] = t.tm_year
        T['month'] = t.tm_mon
        T['day'] = t.tm_mday
        for key, value in T.items():
            setattr(d, key, value)
        return d
x = Date(2018,6,5)
youxi=x.today()
print(youxi.year, youxi.month, youxi.day)
View Code

总结:

当通过非标准方法去创建实例的时候,最好不要对他们的实现做过多的假设,不要直接操作底层的字典__dict__的代码,除非你保证它完全被定义了,否则,一旦类中使用了

__slots__、proprety属性、描述符(魔术方法),那么你的代码就会崩溃。通过使用setattr()来为属性定值,代码就会尽可能的通用。

没有过不去的坎,只有没加够的油!
原文地址:https://www.cnblogs.com/zhoulixiansen/p/9131452.html