我需要在Python 2.7中定义一组灵活的结构(具有简单命名字段集合的对象,以后可以在其中添加新字段,但我不需要方法或继承或类似的东西)。 (上下文是我正在使用struct.unpack_from从二进制文件中读取内容,然后在结果中添加更多数据。)
班级符合要求,例如
class Thing:
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
唯一的缺点是每个字段名称必须写出三次。 collections.namedtuple提供了更精确的定义语法,但您无法向结果对象添加字段。
有没有办法获得一个类的灵活性,至少有一些简短的collections.namedtuple?
答案 0 :(得分:7)
我发现有时有用的模式是
class Obj(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
你可以像
一样使用它p = Obj(x=10, y=20)
答案 1 :(得分:6)
隐藏在argparse
模块中的是Namespace
:
from argparse import Namespace
n = Namespace(foo='Foo', bar='Bar')
n
Out[3]: Namespace(bar='Bar', foo='Foo')
n.bar
Out[4]: 'Bar'
n.hey = 'Hey'
n
Out[6]: Namespace(bar='Bar', foo='Foo', hey='Hey')
答案 2 :(得分:0)
我为此目的写的东西:
def initialize(instance, args):
"""
In __init__, call initialize(self, locals()) to load all passed
arguments.
"""
if 'self' in args:
del args['self']
for k, v in args.items():
setattr(instance, k, v)
class MyClass:
def __init__(self, a, b, c):
initialize(self, locals())
a = MyClass(1, 2, 3)
然而,最后我决定由此引起的可读性不足并不值得保存按键,这对我来说不是一个特别大的问题。
答案 3 :(得分:0)
有没有办法获得至少有一些类的灵活性 collections.namedtuple的简洁性?
只需实例化您的类并为其赋予类属性:
class Namespace(object):
foo = 'bar'
现在,Namespace.foo
返回'bar'
脚本中的样式不正确,但在shell中,您可以设置由分号分隔的多个属性:
>>> class NameSpace(object): foo = 'bar'; baz = {}
>>> NameSpace.baz['quux'] = 'ni'
>>> NameSpace.foo
'bar'
>>> NameSpace.something = 'completely different'
... collections.namedtuple?
嗯,上面的内容更为简短,但下面与collections.namedtuple
更相似,(让你想知道他们在哪里得到了这个想法,不是吗?):
>>> NameSpace = type('NameSpace', (object,), {'foo': 'bar', 'baz': {}})
>>> NameSpace.baz['quux'] = 'ni'
>>> NameSpace.foo
'bar'