我正在尝试创建一个基于 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__
来避免。问题是为什么会发生这种情况。
最佳答案
子类化 str
时需要使用 __new__
而不是 __init__
,参见 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
是一个不可变对象(immutable对象),因此 __init__
对 str
没有意义.您仍然可以也定义一个__init__
方法,但是因为您已经有了__new__
,所以真的没有必要将工作分成两个方法.
关于python - 从 str 派生的类的构造函数,具有不同的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12548572/