from collections import namedtuple
FooT = namedtuple('Foo', 'foo bar')
def Foo(foo=None, bar=None):
return FooT(foo,bar)
foo = Foo()
foo.foo = 29
throws attribute error
所以,我的使用情况是一个数据结构,它有可选字段..但如果需要的话应该能够修改它。
from collections import namedtuple
FooT = namedtuple('Foo', 'foo bar')
def Foo(foo=None, bar=None):
return FooT(foo,bar)
foo = Foo()
foo.foo = 29
throws attribute error
所以,我的使用情况是一个数据结构,它有可选字段..但如果需要的话应该能够修改它。
元组在定义时是不可变的。命名元组也遵循这个模式。
在Python3中,似乎有一个名为SimpleNamespace[1]的东西可以使用。但如果你想要使用一个简单的读写数据结构,你可以创建一个类并对其成员设置限制。
defaultdict
应该符合您的需求。它在构建时提供一个函数,每次访问未设置的元素时都会调用它。以下是示例演示:>>> from collections import defaultdict
>>> d = defaultdict(lambda:None)
>>> d['foo'] = 10
>>> d['bar'] = 5
>>> print d['baz']
None
>>> d['baz'] = 15
>>> print d['baz']
15
命名元组(namedtuple)和元组一样不可修改。由于问题涉及到命名元组,有时候使用_replace
方法创建一个新对象是可以接受的(甚至更好)。当然,对同一对象的其他引用将保持不变。
from collections import namedtuple
FooT = namedtuple('Foo', 'foo bar')
def Foo(foo=None, bar=None):
return FooT(foo,bar)
foo = Foo()
foo = foo._replace(foo=29)
class Foo(object):
def __getattr__(self, name):
return None
class Foo(object):
def __init__(foo=None, bar=None):
self.foo = foo
self.bar = bar
foo = Foo()
foo.foo = 29
_replace()
来更新值并返回一个新的不可变结构。请查看typing.NamedTuple
,自3.6.1起,它支持默认值。 - thom_nic