I'm using __init__()
like this in some SQLAlchemy ORM classes that have many parameters (upto 20).
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
Is it "pythonic" to set attributes like this?
I'm using __init__()
like this in some SQLAlchemy ORM classes that have many parameters (upto 20).
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
Is it "pythonic" to set attributes like this?
To me it seems pretty pythonic if you only need this in one place in your code.
The following link provides a more 'generic' approach to the same problem (e.g. with a decorator and some extra functionality), have a look at: http://code.activestate.com/recipes/551763/
Yes. Another way to do this is.
def __init__(self, **kwargs):
self.__dict__.update( kwargs )
Yes, if there's not a "nicer" way of supplying the arguments.
For example, using your ORM classes you mention, perhaps it would be more Python'y to allow..
col = Varchar()
col.index = True
col.length = 255
..rather than..
col = Varchar(index = True, length = 255)
Okay that's not the best example, since the **kwargs
method would actually be nicer.. but my point is you should always consider alternative methods of achieving something, before using sometimes-discouraged things like **kwargs
..
Another thing to keep in mind is you might lose behaviour a user expects, such as raising a TypeError if the user supplies an invalid keyword arg, which could be worked around like..
def __init__(self, **kwargs):
valid_kwargs = ['x', 'y', 'z']
for k, v in kwargs.iteritems():
if k not in valid_kwargs:
raise TypeError("Invalid keyword argument %s" % k)
setattr(self, k, v)
A final thing to consider:
class Hmm:
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
def mymethod(self):
print "mymethod should print this message.."
x = Hmm(mymethod = None)
x.mymethod() # raises TypeError: 'NoneType' object is not callable