2013-05-30 53 views
4

我試圖創建一個從str類型和第二類繼承的派生類。這是問題的,因爲str類型並不簡單地調用__init__,但__new__方法由於其不變性。我知道,__init__和超工作得很好,你需要有相同的調用結構一路下滑。但是下面的實現失敗:__new__和__init__的Python多重繼承與字符串和第二類

class base(object): 
    def __new__(cls, *args, **kwargs): 
     print "NEW BASE:", cls, args, kwargs 
     return super(base, cls).__new__(cls, *args, **kwargs) 

    def __init__(self, *args, **kwargs): 
     print "INIT BASE", args, kwargs 

class foo(base, str): 
    def __new__(cls, *args, **kwargs): 
     return super(foo, cls).__new__(cls, *args, **kwargs) 

    def __init__(self, *args, **kwargs): 
     super(foo, self).__init__(*args, **kwargs) 

這裏foo('cat')作品有:

>> NEW BASE: <class '__main__.foo'> ('cat',) {} 
>> INIT BASE ('cat',) {} 

但有一個說法foo('cat', x=3),它失敗:

>> NEW BASE: <class '__main__.foo'> ('cat',) {'x': 3} 
Traceback (most recent call last): 
    File "inh.py", line 19, in <module> 
    foo('cat', x=3) 
    File "inh.py", line 12, in __new__ 
    return super(foo, cls).__new__(cls, *args, **kwargs) 
    File "inh.py", line 4, in __new__ 
    return super(base, cls).__new__(cls, *args, **kwargs) 
TypeError: str() takes at most 1 argument (2 given) 

可以得到這個由工作改變base.__new__方法:

def __new__(cls, *args, **kwargs): 
    return super(base, cls).__new__(cls) 

但現在我已經改變了調用結構,我覺得會在晚些時候導致我的問題。

如何正確地從一個字符串和第二類繼承?

回答

2

你不能只是做

def __new__(cls, *args, **kwargs): 
    return super(base, cls).__new__(cls) 

,因爲這會導致不正確的呼籲海峽的(你會不會通過允許參數

>>> foo('t') 
NEW BASE: <class '__main__.foo'> ('t',) {} 
INIT BASE ('t',) {} 
'' 

你應該這樣做

def __new__(cls, *args, **kwargs): 
    return super(base, cls).__new__(cls, *args[:1]) 

但如果這能打碎了什麼東西您將使用base類是混入了類__new__方法接受多個參數。

作爲一個選項,也許你應該有類從str繼承但覆蓋方法:

class CarelessStr(str): 
    def __new__(cls, *args, **kwargs): 
     return super(CarelessStr, cls).__new__(cls, *args[:1]) 

class foo(base, CarelessStr): 
    def __new__(cls, *args, **kwargs): 
     return super(foo, cls).__new__(cls, *args, **kwargs) 

    def __init__(self, *args, **kwargs): 
     super(foo, self).__init__(*args, **kwargs) 
+0

你是正確的,我的新未通過的第一個參數。然而,你的解決方案似乎很痛苦,因爲它增加了另一層間接性。誠然,它的工作,但它被認爲是pythonic的方式? – Hooked

+0

我不確定是否有描述任務的通用解決方案。我同意這個解決方案增加了另一個間接層。但是這可能是某些情況下的唯一選擇。 – oleg

+0

太棒了。我沒有發現額外的基地! – Rafe