Python: распаковать словарь внутри метода

В Python я хочу создать новый объект, загрузив в него несколько переменных. Самый простой способ - передать словарь, но это делает программирование очень раздражающим: вместо self.health мне приходится постоянно вызывать self.params['health']. Есть ли способ динамически устанавливать имена переменных (полей)?

Я имею:

DEFAULT_PARAMS = {
    'health': 10,
    'position': []
}

def __init__(self, params = DEFAULT_PARAMS):
    self.params = params
    print self.params['health']

Я хочу иметь:

DEFAULT_PARAMS = {
    'health': 10,
    'position': []
}

class Name():
    def load(self, params):
        # what goes here?

    def __init__(self, params = DEFAULT_PARAMS):
        self.load(params)
        print self.health

4 ответа

Решение
class Name(object):
    def __init__(self, *params):
        self.__dict__.update(DEFAULT_PARAMS)
        self.__dict__.update(params)

b = Name(position=[1,2])
print b.position

Ты можешь использовать

setattr(self, name, value)

создать новый атрибут self с динамическим именем name и значение value, В вашем примере вы могли бы написать

def load(self, params):
    for name, value in params.iteritems():
        setattr(self, name, value)

Если вы используете синтаксис **kwargs, то это делает вашу конструкцию еще более гибкой при создании объекта:

class MyHealthClass(object):
    def __init__(self, *args, **kwargs):
        for key in kwargs:
            setattr(self, key, kwargs[key])
        if not hasattr(self, 'health'):
            raise TypeError('Needs a health')
        print self.health

Затем вы можете вызвать это с помощью своего словаря следующим образом:

>>> myvar = MyHealthClass(**DEFAULT_PARAMS)
10

Или используя ключевые слова args:

>>> myvar = MyHealthClass(healh=10, wealth="Better all the time")
10
>>> print myvar.health
10
>>> print myvar.wealth
Better all the time

Вы можете сделать атрибуты для экземпляра из элементов, поступающих в словарь:

def __init__(self, params=DEFAULT_PARAMS):
  ...
  for k,v in DEFAULT_PARAMS.iteritems():
    setattr(self, escape_attr_name(k), v)
  ...

В escapse_attr_name Вы заботитесь о символах, которые не разрешены в именах атрибутов, но присутствуют в ключах.

Другие вопросы по тегам