Reputation: 282915
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
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
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
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
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
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
Reputation: 122449
class ValidationRule:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
Upvotes: 4
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