sds*_*sds 3 python namedtuple python-2.7
我似乎无法实例化一个namedtuple
子类:
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)
Run Code Online (Sandbox Code Playgroud)
当我尝试创建一个实例时,我得到:
>>> Foo(1,2)
TypeError: __new__() takes exactly 4 arguments (3 given)
Run Code Online (Sandbox Code Playgroud)
我期待Foo(1,2,3)
.
似乎有一种解决方法:使用类方法而不是__init__
:
class Foo(foo):
@classmethod
def get(cls, a, b):
return cls(a=a, b=b, c=a+b)
Run Code Online (Sandbox Code Playgroud)
现在Foo.get(1,2)
确实回来了foo(a=1, b=2, c=3)
.
但是,这看起来很难看.
这是唯一的方法吗?
命名元组是不可变的,您需要使用该__new__
方法:
class Foo(foo):
def __new__(cls, a, b):
return super(Foo, cls).__new__(cls, a=a, b=b, c=a+b)
Run Code Online (Sandbox Code Playgroud)
(注意:__new__
隐式地创建了一个静态方法,因此您需要cls
显式传递参数;该方法返回新创建的实例).
__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)
Run Code Online (Sandbox Code Playgroud)
这样你就可以保持命名元组的内存占用率低.查看__slots__
文档:
一个的动作
__slots__
声明限制为定义它的类.因此,子类将具有一个,__dict__
除非它们也定义__slots__
(它必须只包含任何其他槽的名称).
归档时间: |
|
查看次数: |
116 次 |
最近记录: |