Create an anonymous class instance in python
Question:
Sometimes I need to create an anonymous class instance in python, just like c#:
var o = new {attr1="something", attr2=344};
but in python I do it in this way:
class Dummy: pass
o = Dummy()
o.attr1 = 'something'
o.attr2 = 344
# EDIT 1
print o.attr1, o.attr2
how can I do that in a Pythonic way and a single statement?
Answers:
class attrdict(dict):
def __getattr__(self, key):
return self[key]
o = attrdict(attr1='something', attr2=344)
o.attr1
But it seems like you should probably just use a standard dict.
o = type('Dummy', (object,), { "attr1": "somehing", "attr2": 344 })
o.attr3 = "test"
print o.attr1, o.attr2, o.attr3
I prefer the dict answer from mwhite, but here’s how I’ve done it in the past using the “magic” of kwargs (pun intended).
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
type
while this is not precisely a single statement I think creating a wrapper around the magic of the accepted answer makes it by far more readable.
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)
Output
[('__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
Output
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')
>>>
If you are using Python 3.3 or later, you can use types.SimpleNamespace:
from types import SimpleNamespace
o = SimpleNamespace(attr1="something", attr2=344)
print(o)
# namespace(attr1='something', attr2=344)
Sometimes I need to create an anonymous class instance in python, just like c#:
var o = new {attr1="something", attr2=344};
but in python I do it in this way:
class Dummy: pass
o = Dummy()
o.attr1 = 'something'
o.attr2 = 344
# EDIT 1
print o.attr1, o.attr2
how can I do that in a Pythonic way and a single statement?
class attrdict(dict):
def __getattr__(self, key):
return self[key]
o = attrdict(attr1='something', attr2=344)
o.attr1
But it seems like you should probably just use a standard dict.
o = type('Dummy', (object,), { "attr1": "somehing", "attr2": 344 })
o.attr3 = "test"
print o.attr1, o.attr2, o.attr3
I prefer the dict answer from mwhite, but here’s how I’ve done it in the past using the “magic” of kwargs (pun intended).
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
type
while this is not precisely a single statement I think creating a wrapper around the magic of the accepted answer makes it by far more readable.
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)
Output
[('__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
Output
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')
>>>
If you are using Python 3.3 or later, you can use types.SimpleNamespace:
from types import SimpleNamespace
o = SimpleNamespace(attr1="something", attr2=344)
print(o)
# namespace(attr1='something', attr2=344)