我正在尝试基于str
创建一个简单的派生类,并添加了一个实例变量flag
。由于我不明白的原因,如果我尝试将标志传递给构造函数,我会收到错误:
>>> class Strvalue(str):
def __init__(self, content, flag=None):
str.__init__(self, content)
self.flag = flag
>>> Strvalue("No problem")
'No problem'
>>> Strvalue("Problem", flag=None)
Traceback (most recent call last):
File "<pyshell#113>", line 1, in <module>
Strvalue("Problem", flag=None)
TypeError: str() takes at most 1 argument (2 given)
我已经检查过,在成功的调用中,Strvalue
构造函数确实被调用了 - 我没有错误输入__init__
或类似的东西。那是怎么回事?
编辑根据this question(和@ Martijn的回答),通过覆盖__new__
可以避免问题。问题是为什么这种情况正在发生。
答案 0 :(得分:1)
在对__new__
进行子类化时,您需要使用__init__
而不是str
,请参阅basic customization。
>>> class Strvalue(str):
... def __new__(cls, content, flag=None):
... inst = str.__new__(cls, content)
... inst.flag = flag
... return inst
...
>>> Strvalue('foo', True)
'foo'
>>> foo = Strvalue('foo', True)
>>> foo
'foo'
>>> foo.flag
True
您的代码不会覆盖str.__new__
,因此使用您的两个参数调用原始str.__new__
构造函数,并且它只接受一个。
str
个对象是不可变的,它们在__new__
中构造一个新实例,然后不再被更改;在调用__init__
时,self
是一个不可变对象,因此__init__
的{{1}}没有意义。您仍然可以 定义str
方法,但由于您已经拥有__init__
,因此实际上没有必要将工作分为两种方法。
答案 1 :(得分:1)
您需要覆盖__new__
而不是{或1}} {/ 1}}。