2013-05-30 55 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