Lat*_*der 2 python overriding namedtuple
假设我有这样一个类:
class Foo(namedtuple('Foo', ['f1'])):
def f1(self):
print('Default f1')
def __new__(cls, f1=f1):
return super().__new__(cls, f1)
Run Code Online (Sandbox Code Playgroud)
让我们说我稍后创建一个Foo对象并选择覆盖f1的方法定义,如下所示:
def my_f1():
print("My f1")
foo = Foo(f1=my_f1)
Run Code Online (Sandbox Code Playgroud)
如果我然后尝试:
foo.f1()
Run Code Online (Sandbox Code Playgroud)
我明白了:
Default f1
Run Code Online (Sandbox Code Playgroud)
当然,我正试图打印"我的f1".我也希望f1是可选的.这里发生了什么?是否可以为namedtuple中的方法定义默认实现,然后在new中覆盖它?
您不能同时使用相同名称的方法和插槽.命名元组使用插槽,这些插槽在与方法相同的命名空间中实现为property对象.通过定义一个方法来破坏属性:f1f1
>>> 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>
Run Code Online (Sandbox Code Playgroud)
该property对象只是返回self[0].所以要么f1按位置访问值:
class Foo(namedtuple('Foo', ['f1'])):
def f1(self):
if self[0]:
return self[0]()
print('Default f1')
Run Code Online (Sandbox Code Playgroud)
或者为您的属性指定一个不同的名称,并让f1方法委托给它:
class Foo(namedtuple('Foo', ['f1_callable'])):
def f1(self):
if self.f1_callable:
return self.f1_callable()
print('Default f1')
Run Code Online (Sandbox Code Playgroud)
演示:
>>> 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
Run Code Online (Sandbox Code Playgroud)