创建接受kwargs的str(或int或float或tuple)的子代

Fer*_*dox 4 python subclass parent-child kwargs python-3.x

我需要一个行为类似字符串的类,但也需要额外的类kwargs.因此我子类str:

class Child(str):

    def __init__(self, x, **kwargs):
        # some code ...
        pass


inst = Child('a', y=2)
print(inst)
Run Code Online (Sandbox Code Playgroud)

然而这引起了:

Traceback (most recent call last):
  File "/home/user1/Project/exp1.py", line 8, in <module>
    inst = Child('a', y=2)
TypeError: 'y' is an invalid keyword argument for this function
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为下面的代码没有任何错误:

class Child(object):

    def __init__(self, x, **kwargs):
        # some code ...
        pass


inst = Child('a', y=2)
Run Code Online (Sandbox Code Playgroud)

问题:

  • 为什么我得到不同的行为,试图子类时str,int,float,tuple相比其他类,如等object,list,dict等?
  • 如何创建一个行为类似字符串但具有额外kwargs的类?

bgp*_*ter 7

__new__在这种情况下你需要覆盖,而不是__init__:

>>> class Child(str):
...    def __new__(cls, s, **kwargs):
...       inst = str.__new__(cls, s)
...       inst.__dict__.update(kwargs)
...       return inst
...
>>> c = Child("foo")
>>> c.upper()
'FOO'
>>> c = Child("foo", y="banana")
>>> c.upper()
'FOO'
>>> c.y
'banana'
>>>
Run Code Online (Sandbox Code Playgroud)

这里的回答为什么压倒一切的__init__继承一成不变的类型,比如当不工作str,int以及float:

__new__()主要用于允许不可变类型的子类(如int,str或tuple)自定义实例创建.它也通常在自定义元类中重写,以自定义类创建.