无法动态更改类实例属性

时间:2016-03-14 17:52:04

标签: python

我有一个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 个答案:

答案 0 :(得分:1)

您正在使用名称self_method设置属性:

self.self_method = new_val

这是同一个属性,一遍又一遍。否则它与self_method局部变量中的值无关。

要动态设置属性,请使用setattr() function

setattr(self, self_method, new_val)

这会获取self_method的值,并在self上使用值为new_value的名称设置属性。