Ответ 1
Да. Другой способ сделать это.
def __init__(self, **kwargs):
self.__dict__.update( kwargs )
Я использую __init__()
как это в некоторых ORM-классах SQLAlchemy, которые имеют много параметров (до 20).
def __init__(self, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
Является ли это "pythonic" для установки таких атрибутов?
Да. Другой способ сделать это.
def __init__(self, **kwargs):
self.__dict__.update( kwargs )
Да, если нет "лучшего" способа подачи аргументов.
Например, используя ваши классы ORM, которые вы упомянули, возможно, это будет больше Python'y, чтобы разрешить...
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
Мне кажется, это довольно pythonic, если вам нужно только это в одном месте в вашем коде.
Следующая ссылка предоставляет более "общий" подход к одной и той же проблеме (например, с декоратором и некоторыми дополнительными функциями), посмотрите на: http://code.activestate.com/recipes/551763/