2014-02-17 18 views
7

Ich muss eine Reihe flexibler Strukturen (Objekte mit einer einfachen Sammlung von benannten Feldern, in denen Sie später neue Felder hinzufügen können, aber ich brauche keine Methoden oder Vererbung oder ähnliches) in Python definieren 2.7. (Der Kontext ist, dass ich Sachen aus binären Dateien mit struct.unpack_from lese und dann weitere Daten zu den Ergebnissen hinzufüge.)Kurze flexible Strukturdefinition

Eine Klasse erfüllt die Anforderungen, z.

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

Der einzige Nachteil ist, dass jeder Feldname dreimal ausgeschrieben werden muss. collections.namedtuple gibt eine genauere Definitionssyntax, aber Sie können den resultierenden Objekten keine Felder hinzufügen.

Gibt es eine Möglichkeit, die Flexibilität einer Klasse mit mindestens der Kürze der Sammlungen zu erhalten.namedtuple?

+2

Haben Sie überlegten, ob Sie Diktate verwenden sollten? –

Antwort

6

im argparse Modul Versteckt verwenden ist 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') 
+0

Beachten Sie, dass es in python3.3 + einen 'types.SimpleNamespace' gibt. Es ist intuitiver, das zu verwenden, weil Sie nicht erwarten, "argparse" zu benötigen, wenn Sie Befehlszeilen nicht analysieren. – Bakuriu

7

Ein Muster, das ich manchmal nützlich fanden

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

und Sie können es wie

p = Obj(x=10, y=20) 
0

Etwas, das ich schrieb für diesen Zweck:

Am Ende entschied ich jedoch, dass die fehlende Lesbarkeit, die dadurch verursacht wurde, die gespeicherten Tastenanschläge nicht wert war, es war kein besonders großes Problem für mich.

0

Gibt es eine Möglichkeit, die Flexibilität einer Klasse mit mindestens einigen der Kürze der Sammlungen zu erhalten.namedtuple?

einfach Ihre Klasse instanziiert und geben es Klassenattribute:

class Namespace(object): 
    foo = 'bar' 

und jetzt, Namespace.foo kehrt 'bar'

Bad Stil in einem Skript, aber in einer Schale, können Sie mehrere Attribute gesetzt getrennt durch Semikolons:

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

... collections.namedtuple?

Nun, die oben noch kurz, aber die unten ist ein bisschen ähnlich wie collections.namedtuple, (macht man sich fragen, wo sie auf die Idee gekommen, nicht wahr?):

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