【发布时间】:2017-12-05 12:07:33
【问题描述】:
当我需要一个快速的一次性类时,我发现自己经常在我的 python 代码中编写这个类。
class Struct(object):
def __init__( self, **kwargs ):
for k in kwargs:
setattr(self,k,kwargs[k])
基本的想法是这样我就可以快速做这样的事情:
foo = Struct( bar='one', baz=1 )
print foo.bar
foo.baz += 1
foo.novo = 42 # I don't do this as often.
当然,这不能很好地扩展,添加方法也很疯狂,但即便如此,我也有足够的纯数据一次性类,我一直在使用它。
这就是我认为namedtuple 将会成为的样子。但是namedtuple的语法大而笨重。
在标准库中我还没有找到可以做到这一点或更好的东西吗?
这是坏坏的风格吗?还是它有一些隐藏的缺陷?
更新
两个具体的例子来说明为什么我不只使用字典。这两个例子都可以用 dict 来完成,但它显然不是惯用的。
#I know an order preserving dict would be better but they don't exist in 2.6.
closure = Struct(count=0)
def mk_Foo( name, path ):
closure.count += 1
return (name, Foo( name, path, closure.count ))
d = dict([
mk_Foo( 'a', 'abc' ),
mk_Foo( 'b', 'def' ),
# 20 or so more
] )
@contextmanager
def deleter( path ):
control = Struct(delete=True,path=path)
try:
yield control
finally:
if control.delete:
shutil.rmtree(path)
with deleter( tempfile.mkdtemp() ) as tmp:
# do stuff with tmp.path
# most contexts don't modify the delete member
# but occasionally it's needed
if keep_tmp_dir:
tmp.delete = False
【问题讨论】:
-
只使用字典有什么问题? x = {'baz':1} x['baz'] += 1
-
namedtuple是tuple,因此您无法更改其内容。 -
@JochenRitzel,您可以致电
_replace。例如:p = Point(x=11, y=22)...p._replace(x=33)...Point(x=33, y=22) -
查看answer 的类似问题。
标签: python