以下代码有效:
class Foo(tuple):
def __init__(self, b):
super(Foo, self).__init__(tuple(b))
if __name__ == '__main__':
print Foo([3, 4])
$python play.py
结果:
play.py:4: DeprecationWarning: object.__init__() takes no parameters
super(Foo, self).__init__(tuple(b))
(3, 4)
但不是以下内容:
class Foo(tuple):
def __init__(self, a, b):
super(Foo, self).__init__(tuple(b))
if __name__ == '__main__':
print Foo(None, [3, 4])
$python play.py
结果:
Traceback (most recent call last):
File "play.py", line 7, in <module>
print Foo(None, [3, 4])
TypeError: tuple() takes at most 1 argument (2 given)
为什么?
解决方法:
因为元组是不可变的,所以你必须覆盖__new__:
object.__new__(cls[, ...])
Called to create a new instance of
classcls
.__new__()
is a static
method (special-cased so you need not
declare it as such) that takes the
class of which an instance was
requested as its first argument. The
remaining arguments are those passed
to the object constructor expression
(the call to the class). The return
value of__new__()
should be the new
object instance (usually an instance
ofcls
).Typical implementations create a new
instance of the class by invoking the
superclass’s__new__()
method usingsuper(currentclass, cls).__new__(cls[, ...])
with appropriate arguments and
then modifying the newly-created
instance as necessary before returning
it.If
__new__()
returns an instance ofcls
, then the new instance’s__init__()
method will be invoked like__init__(self[, ...])
, where self is the new instance and the remaining
arguments are the same as were passed
to__new__()
.If
__new__()
does not return an
instance ofcls
, then the new
instance’s__init__()
method will not
be invoked.
__new__()
is intended mainly to allow subclasses of immutable types (likeint
,str
, ortuple
) to customize
instance creation. It is also commonly
overridden in custom metaclasses in
order to customize class creation.