老樣子,拋出個問題,我們想要創建一個實例,但是由於某些原因想繞過__init__方法,用別的方式來進行創建。 舉個慄子 小賤賤反序列化數據,或者說實現一個類方法將其作為備選的構造函數,都屬於這種情況。舉個慄子: 採用下麵的方法可以不用調用__init__()創建一個Date實例: 但是註意,此時使用 ...
老樣子,拋出個問題,我們想要創建一個實例,但是由於某些原因想繞過__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()來為屬性定值,代碼就會儘可能的通用。