Как вы можете установить атрибуты класса из переменных аргументов (kwargs) в python
Предположим у меня есть класс с конструктором (или другой функции), которая принимает переменное число аргументов, а затем устанавливает их в качестве атрибутов класса условно.
Я мог бы установить их вручную, но кажется, что переменные параметры достаточно распространены в python, что для этого должна быть общая идиома. Но я не уверен, как это сделать динамически.
У меня есть пример использования eval, но это вряд ли безопасно. Я хочу знать правильный способ сделать это -- может лямда?
class Foo:
def setAllManually(self, a=None, b=None, c=None):
if a!=None:
self.a = a
if b!=None:
self.b = b
if c!=None:
self.c = c
def setAllWithEval(self, **kwargs):
for key in **kwargs:
if kwargs[param] != None
eval("self." + key + "=" + kwargs[param])
8 ответов:
вы можете обновить
__dict__
атрибут (который представляет атрибуты класса в виде словаря) с ключевыми аргументами:class Bar(object): def __init__(self, **kwargs): self.__dict__.update(kwargs)
затем вы можете:
>>> bar = Bar(a=1, b=2) >>> bar.a 1
и с чем-то вроде:
allowed_keys = ['a', 'b', 'c'] self.__dict__.update((k, v) for k, v in kwargs.items() if k in allowed_keys)
вы можете фильтровать ключи заранее (используйте
iteritems
вместоitems
если вы все еще используете Python 2.икс.)
большинство ответов здесь не охватывают хороший способ инициализации всех разрешенных атрибутов только до одного значения по умолчанию. Итак, чтобы добавить к ответам, данным @fqxp и @mmj:
class Myclass: def __init__(self, **kwargs): # all those keys will be initialized as class attributes allowed_keys = set(['attr1','attr2','attr3']) # initialize all allowed keys to false self.__dict__.update((key, False) for key in allowed_keys) # and update the given keys by their given values self.__dict__.update((key, value) for key, value in kwargs.items() if key in allowed_keys)
Я предлагаю вариант ответ fqxp, который, помимо атрибуты, позволяет установить значения по умолчанию для атрибутов:
class Foo(): def __init__(self, **kwargs): # define default attributes default_attr = dict(a=0, b=None, c=True) # define (additional) allowed attributes with no default value more_allowed_attr = ['d','e','f'] allowed_attr = list(default_attr.keys()) + more_allowed_attr default_attr.update(kwargs) self.__dict__.update((k,v) for k,v in default_attr.items() if k in allowed_attr)
Это Python 3.X код, для Python 2.x вам нужна хотя бы одна настройка,
iteritems()
на местеitems()
.
class SymbolDict(object): def __init__(self, **kwargs): for key in kwargs: setattr(self, key, kwargs[key]) x = SymbolDict(foo=1, bar='3') assert x.foo == 1
Я вызвал класс
SymbolDict
потому что это по существу словарь, который работает с использованием символов вместо строк. Другими словами, вы делаетеx.foo
вместоx['foo']
но под одеялом это действительно то же самое происходит.
этот самый простой через larsks
class Foo: def setAllWithKwArgs(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value)
мой пример:
class Foo: def __init__(self, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) door = Foo(size='180x70', color='red chestnut', material='oak') print(door.size) #180x70