Hoo*_*ked 5 python inheritance multiple-inheritance abc super
我正在尝试创建一个继承自str类型和第二类的派生类.这是有问题的,因为str类型不是简单地调用__init__,而是__new__由于其不变性而导致的方法.我知道for __init__和super工作得很好,你需要一直拥有相同的调用结构.但是,以下实现失败:
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)
Run Code Online (Sandbox Code Playgroud)
这foo('cat')适用于:
>> NEW BASE: <class '__main__.foo'> ('cat',) {}
>> INIT BASE ('cat',) {}
Run Code Online (Sandbox Code Playgroud)
但是有了一个参数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)
Run Code Online (Sandbox Code Playgroud)
我可以通过将base.__new__方法更改为:
def __new__(cls, *args, **kwargs):
return super(base, cls).__new__(cls)
Run Code Online (Sandbox Code Playgroud)
但是现在我改变了调用结构,我觉得这会让我后来遇到问题.
如何从字符串和第二类中正确继承?
你不能只是做
def __new__(cls, *args, **kwargs):
return super(base, cls).__new__(cls)
Run Code Online (Sandbox Code Playgroud)
因为这会导致对 str 的new的错误调用(您不会传递允许的参数
>>> foo('t')
NEW BASE: <class '__main__.foo'> ('t',) {}
INIT BASE ('t',) {}
''
Run Code Online (Sandbox Code Playgroud)
你应该做类似的事情
def __new__(cls, *args, **kwargs):
return super(base, cls).__new__(cls, *args[:1])
Run Code Online (Sandbox Code Playgroud)
但是,如果您将类用作base类的 mixin,而该__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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2347 次 |
| 最近记录: |