我在一些SQLAlchemy ORM类中使用__init__()
,这些类有很多参数(最多20个)。
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
设置这样的属性是“pythonic”吗?
答案 0 :(得分:24)
是。另一种方法是。
def __init__(self, **kwargs):
self.__dict__.update( kwargs )
答案 1 :(得分:8)
是的,如果没有“更好”的方式提供论据。
例如,使用您提到的ORM类,也许允许更多Python.y
col = Varchar()
col.index = True
col.length = 255
..而不是..
col = Varchar(index = True, length = 255)
好吧,这不是最好的例子,因为**kwargs
方法实际上会更好......但我的观点是,在使用有时候令人沮丧的事情之前,你应该总是考虑实现某些事情的替代方法,**kwargs
..
要记住的另一件事是您可能会丢失用户期望的行为,例如,如果用户提供无效的关键字arg,则会引发TypeError,这可能会像...一样解决。
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)
最后要考虑的事情是:
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
答案 2 :(得分:1)
对我而言,如果您只需要在代码中的某个位置使用它,那么它似乎非常pythonic。
以下链接提供了针对同一问题的更“通用”方法(例如,使用装饰器和一些额外功能),请查看:http://code.activestate.com/recipes/551763/