想搞一個對象繼承自str,而後存一些額外信息用來標識這個字符串,而後理所固然地重寫了__init__發現跪了:html
class newstring(str): def __init__(self, value, othervalue): str.__init__(self, value) self.othervalue = othervalue astring = newstring('hello', 'othervalue') # Fail
後來發現str的__new__是在__init__前調用的,而後str在__new__的時候發現參數不對就拋了個異常。這麼詭異的行爲主要是由於str的__new__就返回了個新的實例,而__init__沒毛用。Python裏面的str大概是這個樣子:htm
class newstring(str): def __new__(cls, value): return str.__new__(cls, value) def __init__(self, value): pass
那麼想要繼承str並在構造時增長一個參數咋整呢,能夠重寫__new__:對象
class newstring(str): def __new__(cls, value, othervalue): return str.__new__(cls, value) def __init__(self, value, othervalue): self.othervalue = othervalue
或者更簡單粗暴的,用*args和**kwargs做爲參數重寫__new__以繞過__new__的參數檢查,而後__init__就能夠正常調用了:繼承
class newstring(str): def __new__(cls, value, *args, **keywargs): return str.__new__(cls, value) def __init__(self, value, othervalue): self.othervalue = othervalue
而後這樣構造的newstring長的跟str一個樣,而且能夠攜帶額外信息,有一點須要注意,就是str是個不可變對象,因此newstring構造出來後就別YY能修改它的值了…ip