简洁灵活的结构定义

时间:2014-02-17 14:52:39

标签: python

我需要在Python 2.7中定义一组灵活的结构(具有简单命名字段集合的对象,以后可以在其中添加新字段,但我不需要方法或继承或类似的东西)。 (上下文是我正在使用struct.unpack_from从二进制文件中读取内容,然后在结果中添加更多数据。)

班级符合要求,例如

class Thing:
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

唯一的缺点是每个字段名称必须写出三次。 collections.namedtuple提供了更精确的定义语法,但您无法向结果对象添加字段。

有没有办法获得一个类的灵活性,至少有一些简短的collections.namedtuple?

4 个答案:

答案 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'