Да. Еще один способ сделать это.
def __init__(self, **kwargs):
self.__dict__.update( kwargs )
Да, если нет «более приятного» способа предоставления аргументов.
Например, используя упомянутые вами классы ORM, возможно, это было бы более Python'ы позволяют ..
col = Varchar()
col.index = True
col.length = 255
.. а не ..
col = Varchar(index = True, length = 255)
Хорошо, это не лучший пример, так как метод ** kwargs
на самом деле будет лучше ... но я хочу сказать, что вы должны всегда рассматривайте альтернативные методы достижения чего-либо, прежде чем использовать иногда обескураживающие вещи, такие как ** kwargs
..
Еще одна вещь, которую нужно иметь в виду, это то, что вы можете потерять поведение, которое ожидает пользователь, например, вызвать ошибку TypeError, если пользователь вводит недопустимое ключевое слово arg, которое можно обойти, например ..
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
Мне кажется довольно пифоничным, если вам нужно это только в одном месте в вашем коде.
Следующая ссылка предоставляет более «общий» подход к той же проблеме (например, с декоратором и некоторыми дополнительными функциями), посмотрите на: http://code.activestate.com/recipes/551763/