创建接受 kwargs 的 str(或 int 或 float 或元组)的 child
Create child of str (or int or float or tuple) that accepts kwargs
我需要一个 class,它的行为类似于字符串,但还需要额外的 kwargs
。因此我子class str
:
class Child(str):
def __init__(self, x, **kwargs):
# some code ...
pass
inst = Child('a', y=2)
print(inst)
然而,这提出了:
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
这很奇怪,因为下面的代码没有任何错误:
class Child(object):
def __init__(self, x, **kwargs):
# some code ...
pass
inst = Child('a', y=2)
问题:
- 为什么我在尝试 subclass
str
、int
、float
、tuple
等时得到的行为与其他 [=40] 不同=]像 object
、list
、dict
等?
- 如何创建一个 class 其行为类似于字符串但具有
额外的 kwargs?
在这种情况下,您需要覆盖 __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'
>>>
请参阅 here 了解为什么在子类化 str
、int
和 float
等不可变类型时覆盖 __init__
不起作用的答案:
__new__()
is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also
commonly overridden in custom metaclasses in order to customize class
creation.
我需要一个 class,它的行为类似于字符串,但还需要额外的 kwargs
。因此我子class str
:
class Child(str):
def __init__(self, x, **kwargs):
# some code ...
pass
inst = Child('a', y=2)
print(inst)
然而,这提出了:
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
这很奇怪,因为下面的代码没有任何错误:
class Child(object):
def __init__(self, x, **kwargs):
# some code ...
pass
inst = Child('a', y=2)
问题:
- 为什么我在尝试 subclass
str
、int
、float
、tuple
等时得到的行为与其他 [=40] 不同=]像object
、list
、dict
等? - 如何创建一个 class 其行为类似于字符串但具有 额外的 kwargs?
在这种情况下,您需要覆盖 __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'
>>>
请参阅 here 了解为什么在子类化 str
、int
和 float
等不可变类型时覆盖 __init__
不起作用的答案:
__new__()
is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.