mpen
mpen

Reputation: 282915

How do I copy **kwargs to self?

Is there a way that I can define __init__ so keywords defined in **kwargs are assigned to the class?

For example, if I were to initialize a ValidationRule class with ValidationRule(other='email'), the value for self.other should be added to the class without having to explicitly name every possible kwarg.

class ValidationRule:
    def __init__(self, **kwargs):
        # code to assign **kwargs to .self

Upvotes: 24

Views: 13090

Answers (7)

ony
ony

Reputation: 13223

I think somewhere on the stackoverflow I've seen such solution. Anyway it can look like:

class ValidationRule:
    __allowed = ("other", "same", "different")
    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
            assert( k in self.__class__.__allowed )
            setattr(self, k, v)

This class will only accept arguments with a whitelisted attribute names listed in __allowed.

Upvotes: 37

Greg
Greg

Reputation: 2034

This could be considered nicer than updating __dict__:

class C:
    def __init__(self, **kwargs):
        vars(self).update(kwargs)

>>> c = C(a='a', b='b')
>>> c.a   # returns 'a'
>>> c.b   # returns 'b'

Upvotes: 3

user394430
user394430

Reputation: 2957

I found the above answers helpful and then refined:

class MyObj(object):
    def __init__(self, key1=1, key2=2, key3=3):
        for (k, v) in locals().iteritems():
            if k != 'self':
                setattr(self, k, v)

Test:

>>> myobj = MyObj(key1=0)
>>> print myobj.key1
0

And validation is also there:

>>> myobj = MyObj(key4=4)
TypeError: __init__() got an unexpected keyword argument 'key4'

Upvotes: 0

Ruslan Spivak
Ruslan Spivak

Reputation: 1760

You can set your kwargs arguments by updating __dict__ attribute of the instance.

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

Upvotes: 3

Gabe
Gabe

Reputation: 86718

This may not be the cleanest way, but it works:

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

I think I prefer ony's solution because it restricts available properties to keep you out of trouble when your input comes from external sources.

Upvotes: 20

newacct
newacct

Reputation: 122449

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

Upvotes: 4

sth
sth

Reputation: 229663

You could do something like this:

class ValidationRule:
   def __init__(self, **kwargs):
      for (k, v) in kwargs.items():
         setattr(self, k, v)

Upvotes: 13

Related Questions