2016-03-14 6 views
0

У меня есть класс оболочки Redshift, где я хочу иметь возможность передавать в последовательности name, values, которая заменит текущие атрибуты экземпляра. В настоящее время я изо всех сил стараюсь, чтобы он изменил эти атрибуты экземпляра. Вот мой код:Неисправность динамически меняет атрибуты экземпляра класса

def __repr__(self): 
     return ('Table: {table}\nManifest URL: {manifest}\nUnload URL: ' 
       '{unload}\nS3 Credentials: {s3_creds}\nDev DB Credentials: ' 
       '{dev_db}\nProd DB Credentials: {prod_db}\nSafe Load: ' 
       '{safe_load}\nTruncate: {truncate}'.format(
      table=self._table_name, 
      manifest=self._manifest_url, 
      unload=self._unload_url, 
      s3_creds=self._s3_credentials, 
      dev_db=self._dev_db_credentials, 
      prod_db=self._prod_db_credentials, 
      safe_load=self._safe_load, 
      truncate=self._truncate 
     )) 


class RedshiftLoads(RedshiftBase): 
    def change_attrs(self, new_attributes): 
     """ 
     Changes the instance attributes. 

     :param new_attributes: A sequence (or sequence of sequences) that 
     contains the name and new values (name, new_value) 

     :return: None 
     """ 

     valid_attribute_names = { 
      'table_name': '_table_name', 
      'manifest_url': '_manifest_url', 
      'unload_url': '_unload_url', 
      's3_credentials': '_s3_credentials', 
      'dev_db_credentials': '_dev_db_credentials', 
      'prod_db_credentials': '_prod_db_credentials', 
      'safe_load': '_safe_load', 
      'truncate': '_truncate' 
     } 
     for attr_name, new_val in new_attributes: 
     if attr_name not in valid_attribute_names: 
      raise ValueError('Must be one of the following values: ' 
          '{attrs}'.format(
       attrs=valid_attribute_names.keys())) 
     else: 
      self_method = valid_attribute_names.get(attr_name) 
      print(attr_name) 
      print(self_method) 
      self.self_method = new_val 

Вот как я проверяю его:

In[3]: rs = aws.RedshiftLoads('s3_creds', 'db_creds') 
In[4]: rs.change_attrs((('table_name', 'Test Table'), ('safe_load', True))) 
table_name 
_table_name 
safe_load 
_safe_load 
In[5]: print(rs) 
Table: None 
Manifest URL: None 
Unload URL: None 
S3 Credentials: s3_creds 
Dev DB Credentials: None 
Prod DB Credentials: db_creds 
Safe Load: False 
Truncate: False 

ответ

1

Вы устанавливаете атрибут по имени self_method:

self.self_method = new_val 

Это тот же атрибут, снова и снова. Он иначе не имеет отношения к значению в локальной переменной self_method.

Чтобы динамически установить атрибут, используйте setattr() function:

setattr(self, self_method, new_val) 

Это имеет значение self_method и устанавливает атрибут с таким именем на self со значением new_value.

+0

Хорошо, что имеет смысл, но не могли бы вы объяснить, как я мог бы моделировать это поведение с помощью моего кода, не используя 'setattr'? Я попытался поместить 'self._table_name' в качестве значения в' dict_attribute_names' 'dict', и он тоже не сделал этого. – flybonzai