2015-05-27 3 views
2

Я использую python для создания создателя персонажей подземелий и драконов, и в настоящее время я программирую оружие. Я воссоздал какой-то код, который не работал в предыдущих подобных средах, и мне было интересно, как он работает, не требуя инструкции if для каждой отдельной переменной, так что может быть доступно редактирование дополнительных свойств и элементов.Создание переменной внутри цикла for

Целью является создание Оружия (Объекта), которое имеет только связанные с ним Свойства (переменные).

Текущий код:

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = [finesse, light, thrown, two_handed, versatile] 
     for prop in property_list: 
      if prop != 0: 
       self.prop = prop 

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 

В настоящее время переменная не будет создана для оружия; таким образом

dagger.finesse 

Не существует. В идеале 'finesse' будет храниться в переменной dagger.finesse, тогда как переменная dagger.two_handed не будет создана кодом.

Возможно, я пропустил что-то простое, и могут быть повторяющиеся вопросы, но я не могу найти аналогичный вопрос с ответом, который я ищу.

Спасибо всем, кто ответил

редактируют

Спасибо @WKPlus некоторой помощи форматирования; Я новичок в веб-сайте stackoverflow

Я понял благодаря @abarnert, что лучший способ сделать это состоит в том, чтобы иметь свойства, перечисленные в переменной, и проверить эту переменную позже в коде для свойства, например так

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = [finesse, light, thrown, two_handed, versatile] 
     self.properties = [] 
     for prop in property_list: 
      if prop != 0: 
       self.properties.append(prop) 

Однако я по-прежнему заинтересован в том, как может ответить мой первоначальный вопрос, так как он все еще может быть полезно запустить что-то вроде моего оригинала без заявления об исключении.

+2

Почему вы хотите 'Weapon.finesse' быть строка '' finesse'' или несуществующая? Разве было бы лучше, если бы это было, скажем, bool, что верно для кинжалов и фальшивых для клубов? – abarnert

+0

Подумайте, как вы собираетесь это использовать. Вы хотите попробовать: player.weapon.finesse, кроме AttributeError: 'весь код? – abarnert

+0

В идеале было бы несколько подклассов «Оружие». – TigerhawkT3

ответ

3

Это будет работать:

class Weapon: 
    def __init__(self, finesse=False, light=False, thrown=False, two_handed=False, 
       versatile=False): 
     props = locals() 
     props.pop('self') 
     for prop, value in props.items(): 
      if value: 
       setattr(self, prop, value) 

Сейчас:

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 

или:

dagger = Weapon('finesse', 'light', 'thrown') 
  1. Я использую аргументы по умолчанию, которые я установил в False. Поэтому, если вы не предоставите их , они будут False.

  2. locals() дает вам словарь всех локальных переменных, определенных до сих пор. Здесь приведены аргументы __init__(). Поскольку вы не хотите self.self, используйте props.pop('self'), чтобы удалить его.

  3. self.prop = prop does нет работа.

    Например, если вы класс A и переменная x:

    class A(object): 
        pass 
    x = 1 
    

    Это:

    for obj in [x]: 
        A.obj = obj 
    

    дает атрибут obj

    >>> A.obj 
    1 
    

    где это:

    setattr(A, 'x', x) 
    

    дает атрибут x:

    >>> A.x 
    1 
    

    Вам нужно setattr(self, name, value) установить атрибут программно.

+0

@PeterGibson Все еще работает над этим. ;) –

4

Вы можете использовать **kwargs и setattr:

class Weapon: 
    def __init__(self, **kwargs): 
     property_list = ['finesse', 'light', 'thrown', 'two_handed', 'versatile'] 
     for prop in property_list: 
      setattr(self, prop, kwargs.get(prop, False)) 

dagger = Weapon(finesse=True, light=True, thrown=True) 

Это будет выглядеть для любого из свойств в property_list в переданных аргументов и установить этот атрибут self. Если свойство не найдено, оно устанавливается в False.

0

Вместо использования setattr установить атрибут, ваш может также проанализировать ваши аргументы в Словаре и обновить атрибут __dict__ с ним:

class Weapon: 
    def __init__(self, finesse, light, thrown, two_handed, versatile): 
     property_list = ['finesse', 'light', 'thrown', 'two_handed', 'versatile'] 
     property_values = dict([(name,eval(name)) for name in property_list]) 
     self.__dict__.update(property_values) 

dagger = Weapon('finesse', 'light', 'thrown', 0, 0) 
print dagger.finesse 
Смежные вопросы