在Python中重寫namedtuple
對象的長度方法比您預期的要枯燥乏味。天真的做法,爲什麼namedtuple._make檢查返回值的長度?
from collections import namedtuple
class Rule(namedtuple('Rule', ['lhs', 'rhs'])):
def __len__(self):
return len(self.rhs)
r = Rule('S', ['NP', 'Infl', 'VP'])
new_r = r._replace(lhs='CP') # raises a TypeError
不起作用。如果你檢查類(可作爲_source
屬性)的實際的源代碼,你可以看到,_make
(其中_replace
電話和引發錯誤)是這樣實現的:
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Rule object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != 2:
raise TypeError('Expected 2 arguments, got %d' % len(result))
return result
有趣的是,檢查以確保返回值的長度爲2。這使得它更難以覆蓋的元組的__len__
方法,因爲如果它返回比2
其他長度的值這是可能的_make
會抱怨通過傳遞總是返回2到01的「len
」函數來防止此行爲:
from collections import namedtuple
class Rule(namedtuple('Rule', ['lhs', 'rhs'])):
def _make(self, *args, len=lambda _: 2, **kwargs):
return super()._make(*args, len=len, **kwargs)
def __len__(self):
return len(self.rhs)
r = Rule('S', ['NP', 'Infl', 'VP'])
new_r = r._replace(lhs='CP') # fine
我的問題是,爲什麼是這個長度檢查不一定是第一名,而且是安全的替代_make
所以它不這樣做呢?
「在Python中重寫namedtuple對象的長度方法比您期望的要冗長乏味 - 」您爲什麼要這麼做?這似乎是一個可怕的想法,會導致各種錯誤,即使除了這個錯誤。 – user2357112