0

Similarly to this question I would like to pass the attributes from a dictionary to an instance of a class, but creating the class using type, like this:

attrs = { 'name': 'Oscar', 'lastName': 'Reyes', 'age':32 }

e = type('Employee', (object,),attrs)()

But when I do this the attributes are belonging to the class, not only to the instance. If I create two instances using:

e = type('Employee', (object,), attrs)()
f = type('Employee', (object,), attrs)()

They will actually be two different classes.

I wanted to create a class that accepts **kwargs and *args in __init__(), like:

class Employee(object):
    def __init__(self, *args, **kwargs):
        self.args = args
        for k,v in kwargs.items():
            setattr(self, k, v)

using type(). So that:

MyClass = type('Employee', (object,), {})

Would allow:

e = MyClass( **kwargs )
Community
  • 1
  • 1
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234

1 Answers1

3

No problem. You just need to write the function and include it in the dictionary that you pass to type under the key '__init__'

def func(self,*args,**kwargs):
    self.args = args
    for k,v in kwargs.items():
        setattr(self,k,v)

MyClass = type('Employee',(object,),{'__init__':func})
e = MyClass(name='john')
print (e.name) #'john'

You can even "delete" func when you're done creating the class if it makes you feel better about keeping your namespace clear:

MyClass = type('Employee',(object,),{'__init__':func})
#clean up, clean up, everybody everywhere, clean up clean up, everybody do your share ...
del func
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • The for-loop can be simplified to `vars(self).update(kwargs)`. – Sven Marnach Jun 04 '13 at 12:50
  • 1
    @SvenMarnach -- In a vast majority of the cases yes. It can't be simplified if the class has `__slots__` though. But the advantage there is that you could even do that with a `lambda` function: `{'__init__':lambda self,**kwargs:vars(self).update(kwargs)}` – mgilson Jun 04 '13 at 12:54