Créer une instance de classe anonyme en python

Parfois, j'ai besoin de créer une instance de classe anonyme en python, tout comme c#:

var o= new {attr1="somehing", attr2=344};

, Mais en python, je le fais de cette façon:

class Dummy: pass
o = Dummy()
o.attr1 = 'something'
o.attr2 = 344
#EDIT 1
print o.attr1, o.attr2

Comment faire cela de manière pythonique dans une seule instruction?

22
demandé sur pylover 2012-12-16 03:34:10

5 réponses

o = type('Dummy', (object,), { "attr1": "somehing", "attr2": 344 })
o.attr3 = "test"
print o.attr1, o.attr2, o.attr3
32
répondu rid 2012-12-16 00:03:00

De Type

Bien que ce ne soit pas précisément une seule déclaration, je pense que la création d'un wrapper autour de la magie de la réponse acceptée la rend de loin plus lisible.

import inspect 

# wrap the type call around a function 
# use kwargs to allow named function arguments
def create_type(name, **kwargs):
    return type(name, (object,), kwargs)

# example call to make a structure
p = create_type('foobar', xxx='barfoo', seti=0)

assert p.xxx == 'barfoo'
assert p.seti == 0

print inspect.getmembers(p)

Sortie

[('__class__', <type 'type'>),
 ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>),
 ('__dict__', <dictproxy object at 0x9a5050>),
 ('__doc__', None),
 ('__format__', <method '__format__' of 'object' objects>),
 ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>),
 ('__hash__', <slot wrapper '__hash__' of 'object' objects>),
 ('__init__', <slot wrapper '__init__' of 'object' objects>),
 ('__module__', '__main__'),
 ('__new__', <built-in method __new__ of type object at 0x399c578460>),
 ('__reduce__', <method '__reduce__' of 'object' objects>),
 ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>),
 ('__repr__', <slot wrapper '__repr__' of 'object' objects>),
 ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>),
 ('__sizeof__', <method '__sizeof__' of 'object' objects>),
 ('__str__', <slot wrapper '__str__' of 'object' objects>),
 ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x919370>),
 ('__weakref__', <attribute '__weakref__' of 'foobar' objects>),
 # here they are
 ('seti', 0),
 ('xxx', 'barfoo')]

Namedtuple

from collections import namedtuple

d = { 'a' : 'foo', 'b' : 'bar' }
foobar = namedtuple('foobar', d.keys())(**d)
print foobar

Sortie

Python 2.7.5 (default, May 30 2013, 16:55:57) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import namedtuple
>>> d  =  { 'a' : 'foo', 'b' : 'bar' }
>>> foobar = namedtuple('foobar', d.keys())(**d)
>>> print foobar
foobar(a='foo', b='bar')
>>> 
9
répondu Alex 2014-03-13 14:50:46

Si vous utilisez Python 3.3 ou version ultérieure, vous pouvez utiliser les types .SimpleNamespace :

from types import SimpleNamespace

o = SimpleNamespace(attr1="something", attr2=344)
print(o)

# namespace(attr1='something', attr2=344)
8
répondu Elias Zamaria 2018-02-20 07:53:49
class attrdict(dict):
    def __getattr__(self, key):
        return self[key]

o = attrdict(attr1='something', attr2=344)

o.attr1

, Mais il semble que vous devriez probablement utiliser une norme dict.

2
répondu mwhite 2012-12-16 04:18:42

Je préfère la réponse dict de mwhite, Mais voici comment je l'ai fait dans le passé en utilisant la" magie " de kwargs (jeu de mots).

class ObjectFromDict(object):
    def __init__(**kwargs):
        for k in kwargs:
            if k not in self.__dict__:
                setattr(k,v)

myObj = ObjectFromDict(**{'foo': 'bar', 'baz': 'monkey'})
print myObj.foo #bar
0
répondu bitcycle 2012-12-15 23:43:19