2017-02-21 64 views
0

Я знаю, что большинство из них не являются поклонниками использования exec для динамического назначения. Тем не менее, я хотел бы обрабатывать имена переменных в качестве данных для моих целей (как прагматических, так и эксцентричных).Объем переменных, назначенных exec (variable =) в цикле for?

Рассмотрим следующий пример, который я использую во время инициализации класса

Теперь я динамически присвоить этим переменным

class Example(object): 
     __tree_dict = {"self.genomedir": "genomes", 
       "self.pre_align": "pre_alignment", 
       "self.alignments": "alignments", 
       "self.trimmed": "trimmed", 
       "self.prf_pre": "prf_preprocess", 
       "self.scaled": "scaled", 
       "self.csv": "csv"} 

     def __init__(self, rootdir): 
      self._rootdir = Path(rootdir) 
      self.outdir = self.mksubdir(self._rootdir, "out") 

     for variable, human_readable in self.__tree_dict.items(): 
      try: 
       exec(variable + " = self.mksubdir(self.outdir,human_readable)") 
      except: 
       LOGGER.error("%s failed to initialize as %s, defaulting output to root" (variable, human_readable), exc_info=True) 
       exec(variable + '= Path(self._rootdir)')    

Этот код будет работать, но я не уверен, за исключением обработка действительно будет работать, потому что, когда я добавить, наконец, заявление написать назначение переменной к регистратору, например

 finally: 
      LOGGER.info(variable + "set to %s" % getattr(self, variable)) 

питон переводчик г АЙСы

AttributeError: 'Example' object has no attribute 'self.csv' 

(имя атрибута изменяется во время выполнения, так как словарь не упорядочен - сам атрибут не имеет значения)

Важной проблемой является то, что, когда я ссылаться на новые переменные вне сферы из для цикла они доступны без ошибки атрибута. Их назначение произошло, и они являются атрибутами класса. Эти переменные находятся как в dir (self), так и в себе.

Какая функция python играет здесь, что мешает мне получить доступ к этим переменным внутри блока for (или блока finally)?

EDIT:

Автономный пример:

class Example(object): 
     __vars_to_be_assigned: {"self.foo": "value", "self.bar": "not foo"} 

     def __init__(self): 
      for key, value in self.__vars_to_be_assigned: 
        try: 
         exec(key + " = value") 
        except: 
         print("Exception!") 
        else: 
         print(getattr(self, variable[5:])) 

Этот пример должен поднять AttributeError

+0

Можете ли вы предоставить минимальный, самодостаточный пример? Кроме того, версия Python повлияет на это, так как семантика 'exec' изменилась с Python 2 на 3. –

+0

Вы на Python 3? Вероятно, этот вопрос будет освещен: http://stackoverflow.com/questions/15086040/behavior-of-exec-function-in-python-2-and-python-3 –

+0

Оказывается, что это простая грамматическая ошибка с ссылка атрибута (self не имеет атрибута self.self.attribute). Однако, спасибо, эта ссылка полезна для будущих исследований –

ответ

3

Это действительно плохое использование exec. Намного проще просто сделать:

class Example(object): 
     __tree_dict = {"genomedir": "genomes", 
       "pre_align": "pre_alignment", 
       "alignments": "alignments", 
       "trimmed": "trimmed", 
       "prf_pre": "prf_preprocess", 
       "scaled": "scaled", 
       "csv": "csv"} 

     def __init__(self, rootdir): 
      self._rootdir = Path(rootdir) 
      self.outdir = self.mksubdir(self._rootdir, "out") 

     for variable, human_readable in self.__tree_dict.items(): 
      try: 
       setattr(self, variable, self.mksubdir(self.outdir,human_readable)) 
      except: 
       LOGGER.error("%s failed to initialize as %s, defaulting output to root" (variable, human_readable), exc_info=True) 
       setattr(self, variable, Path(self._rootdir) 

Причина, почему вы получаете ошибку, хотя это просто, что атрибут называется csv, не self.csv. Использование setattr и удаление префикса self. из значений в __tree_dict обеспечит согласованность между настройкой и получением значений.

+0

Спасибо! хороший улов. Простая ошибка. Кроме того, я не рассматривал использование setattr. благодаря –