是否有可能重写Python中的namedtuple方法?
问题描述:
比方说,我有一个这样的类:是否有可能重写Python中的namedtuple方法?
class Foo(namedtuple('Foo', ['f1'])):
def f1(self):
print('Default f1')
def __new__(cls, f1=f1):
return super().__new__(cls, f1)
而且让我们说我以后上创建一个Foo对象,然后选择要覆盖的方法定义,对于F1,就像这样:
def my_f1():
print("My f1")
foo = Foo(f1=my_f1)
如果我然后尝试:
foo.f1()
我得到:
Default f1
我试图让“我的f1”打印,当然。我也希望f1是可选的。这里发生了什么?是否可以为namedtuple中的方法定义默认实现,然后在新的中覆盖它?
答
您不能同时使用同一名称的方法和插槽。被命名的元组使用slots,并且这些被实现为property
对象与方法在相同的命名空间中。通过定义一个方法f1
你打一顿的f1
属性:
>>> from collections import namedtuple
>>> namedtuple('Foo', ['f1']).f1
<property object at 0x1069764c8>
>>> class Foo(namedtuple('Foo', ['f1'])):
... def f1(self):
... print('Default f1')
...
>>> Foo.f1
<unbound method Foo.f1>
的property
对象只返回self[0]
。所以,无论是位置访问f1
值:
class Foo(namedtuple('Foo', ['f1'])):
def f1(self):
if self[0]:
return self[0]()
print('Default f1')
或给你的属性不同名,并有f1
方法委托到:
class Foo(namedtuple('Foo', ['f1_callable'])):
def f1(self):
if self.f1_callable:
return self.f1_callable()
print('Default f1')
演示:
>>> def my_f1():
... print("My f1")
...
>>> class Foo(namedtuple('Foo', ['f1'])):
... def f1(self):
... if self[0]:
... return self[0]()
... print('Default f1')
...
>>> foo = Foo(my_f1)
>>> foo.f1()
My f1
>>> foo = Foo(None)
>>> foo.f1()
Default f1
答
避免在class Foo
内声明f1
。相反,在模块级声明它,并把它作为一个default argument for your namedtuple:
def f1():
print('Default f1')
Foo = namedtuple('Foo', 'f1')
Foo.__new__.__defaults__ = (f1,)
用法:
>>> foo = Foo()
>>> foo.f1()
Default f1
>>> def other_f1():
... print('Another f1')
>>> foo = Foo(f1=other_f1)
>>> foo.f1()
Another f1
在我看来,你想用一个字段的默认值namedtuple。在这种情况下,默认值是可调用的,但它没有太大的区别:http://*.com/questions/11351032/named-tuple-and-optional-keyword-arguments –
@AndreaCorbellini:它使一个巨大的差异,因为处理属性的属性被方法破坏了。 –
@MartijnPieters:只有当你想在'class Foo'中声明'f1'时,它才会有所不同。但是这太过复杂(详情请参阅你自己的答案:P)。在Foo类外声明'f1'并将其设置为默认参数使事情变得更容易。 –