Cannot create an instance of a namedtuple subclass: TypeError: __new__() takes exactly 4 arguments (3 given)
Cannot create an instance of a namedtuple subclass: TypeError: __new__() takes exactly 4 arguments (3 given)
我好像无法实例化一个namedtuple
子class:
from collections import namedtuple
foo = namedtuple("foo",["a","b","c"])
class Foo(foo):
def __init__(self, a, b):
super(Foo, self).__init__(a=a,b=b,c=a+b)
当我尝试创建一个实例时,我得到:
>>> Foo(1,2)
TypeError: __new__() takes exactly 4 arguments (3 given)
我预计 Foo(1,2,3)
。
似乎有一个解决方法:使用 class 方法而不是 __init__
:
class Foo(foo):
@classmethod
def get(cls, a, b):
return cls(a=a, b=b, c=a+b)
现在Foo.get(1,2)
确实returnsfoo(a=1, b=2, c=3)
.
然而,这看起来很难看。
这是唯一的方法吗?
命名元组不可变,您需要使用__new__
method代替:
class Foo(foo):
def __new__(cls, a, b):
return super(Foo, cls).__new__(cls, a=a, b=b, c=a+b)
(注:__new__
隐式做成静态方法,所以需要显式传递cls
参数;方法returns新创建的实例)。
__init__
无法使用,因为它是在实例创建之后调用的,因此将无法再改变元组。
请注意,您确实应该在子类中添加 __slots__ = ()
行;一个命名的元组没有 __dict__
字典使你的记忆混乱,但你的子类 将 除非你添加 __slots__
行:
class Foo(foo):
__slots__ = ()
def __new__(cls, a, b):
return super(Foo, cls).__new__(cls, a=a, b=b, c=a+b)
这样您就可以将命名元组的内存占用保持在较低水平。请参阅 __slots__
文档:
The action of a __slots__
declaration is limited to the class where it is defined. As a result, subclasses will have a __dict__
unless they also define __slots__
(which must only contain names of any additional slots).
我好像无法实例化一个namedtuple
子class:
from collections import namedtuple
foo = namedtuple("foo",["a","b","c"])
class Foo(foo):
def __init__(self, a, b):
super(Foo, self).__init__(a=a,b=b,c=a+b)
当我尝试创建一个实例时,我得到:
>>> Foo(1,2)
TypeError: __new__() takes exactly 4 arguments (3 given)
我预计 Foo(1,2,3)
。
似乎有一个解决方法:使用 class 方法而不是 __init__
:
class Foo(foo):
@classmethod
def get(cls, a, b):
return cls(a=a, b=b, c=a+b)
现在Foo.get(1,2)
确实returnsfoo(a=1, b=2, c=3)
.
然而,这看起来很难看。
这是唯一的方法吗?
命名元组不可变,您需要使用__new__
method代替:
class Foo(foo):
def __new__(cls, a, b):
return super(Foo, cls).__new__(cls, a=a, b=b, c=a+b)
(注:__new__
隐式做成静态方法,所以需要显式传递cls
参数;方法returns新创建的实例)。
__init__
无法使用,因为它是在实例创建之后调用的,因此将无法再改变元组。
请注意,您确实应该在子类中添加 __slots__ = ()
行;一个命名的元组没有 __dict__
字典使你的记忆混乱,但你的子类 将 除非你添加 __slots__
行:
class Foo(foo):
__slots__ = ()
def __new__(cls, a, b):
return super(Foo, cls).__new__(cls, a=a, b=b, c=a+b)
这样您就可以将命名元组的内存占用保持在较低水平。请参阅 __slots__
文档:
The action of a
__slots__
declaration is limited to the class where it is defined. As a result, subclasses will have a__dict__
unless they also define__slots__
(which must only contain names of any additional slots).