Clear, flexible structure definition

I need to define a bunch of flexible structures (objects with a simple collection of named fields, where you can add new fields later, but I don't need methods or inheritance or anything like that) in Python 2.7. (The context is that I read material from binary files using struct.unpack_from, and then add additional data to the results.)

The class meets the requirements, for example

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

The only drawback is that each field name must be written out three times. collections.namedtuple provides a more precise definition syntax, but you cannot add fields to the resulting objects.

Is there a way to get class flexibility with at least some multiplicity of collections. namedtuple?

+7
python
source share
4 answers

Hidden in the argparse Namespace module:

 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') 
+6
source share

The sample that I found sometimes useful,

 class Obj(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) 

and you can use it as

 p = Obj(x=10, y=20) 
+7
source share

Something I wrote for this purpose:

 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) 

However, in the end, I decided that the lack of readability caused by this was not worth keeping the keys pressed, this was not a particularly big problem for me.

0
source share

Is there any way to get class flexibility, at least with some of the brevity of collections. namedtuple?

Just create an instance of the class and assign class attributes to it:

 class Namespace(object): foo = 'bar' 

and now Namespace.foo returns 'bar'

The style is bad in the script, but in the shell you can set several attributes separated by a semicolon:

 >>> class NameSpace(object): foo = 'bar'; baz = {} >>> NameSpace.baz['quux'] = 'ni' >>> NameSpace.foo 'bar' >>> NameSpace.something = 'completely different' 

... collections.namedtuple?

Well, the above is even more concise, but below is a bit like collections.namedtuple (makes you wonder where they got the idea from, right?):

 >>> NameSpace = type('NameSpace', (object,), {'foo': 'bar', 'baz': {}}) >>> NameSpace.baz['quux'] = 'ni' >>> NameSpace.foo 'bar' 
0
source share

All Articles