4

我正在尝试将__dict__成员添加到由 namedtuple 生成的类中。(__dict__存在于 python 2.7.3 中,但已在 2.7.5 中删除。请参阅http://bugs.python.org/issue15535。它存在并记录在 python 3.3 中。)我的代码使用 vars(nametuple_object),即基于__dict__. 我想在需要时修补课程。

这是我尝试过的:

# Applies to Python 2.7.5 +

C = namedtuple('C', ['x', 'y'])
if not hasattr(C, '__dict__'):
  C.__dict__ = property(C._asdict)

这不起作用,因为 C 继承了 a __dict__,因此 hasattr 始终为 true 并且(强制时)属性分配返回:

Traceback (most recent call last):
  File "namedtuple_dict.py", line 8, in <module>
    C.__dict__ = property(C._asdict)
AttributeError: attribute '__dict__' of 'type' objects is not writable

也许,有没有办法引用未继承的 C 成员?


解决方案

这是我的 namedtuple 包装器,它使用 rdb 的建议,即仅从 namedtuple 类继承而不是尝试修改它:

def namedtuple_with_dict(typename, field_names, **kwargs):

  C = CBase = namedtuple(typename, field_names, **kwargs)
  if 0x02070500 <= sys.hexversion < 0x03000000:
    C = type(typename, (CBase,), {'__dict__': property(CBase._asdict)})
  return C
4

1 回答 1

7

namedtuple 将 __slots__ 设置为一个空元组,这是为了避免为了内存优化而创建 __dict__。这意味着它的设计没有也不能拥有 __dict__ 。当存在 __slots__ 时,您不能分配 __dict__,或为此定义任何新字段。

但是,这不适用于派生类,因此您可以这样做:

CBase = namedtuple('C', ['x', 'y'])

class C(CBase):
    __dict__ = property(CBase._asdict)

print C(1, 2).__dict__
于 2014-01-20T23:54:08.413 回答