我正在寻找一种在设置某些属性时执行一些自定义转义的方法,以及在从我的一个对象中检索这些属性时执行相应的转义代码。我查看了 __setattr__、__getattr__ 和 __getattribute__,但看不到它们与属性的关系。
例如,我有一个类,例如:
class Bundle(object):
def __init__(self):
self.storage = Storage()
@property
def users_name(self):
"""
Get the user's name
"""
return self.storage.users_name
@users_name.setter
def users_name(self, users_name):
"""
Set the user's name
"""
# only permit letters and spaces.
if not re.match('^[A-Za-z ]+$', users_name):
msg = "'%s' is not a valid users_name. It must only contain letters and spaces" % users_name
log.fatal(msg)
raise ConfigurationError(msg)
self.storage.users_name = users_name
...
对象上有几个这样的属性。
我想要的是一种只会影响我的一些属性(例如 users_name,但不影响“存储”)的方法,并且在设置/检索时会转义/取消转义值。
- __getattr__ 似乎不正确,因为应该为新的和现有的属性调用此代码。
- __setattr__ 可能有效,但我不明白它如何适合我的 @property 方法。例如,是否总是调用 __setattr__ 而不是我的自定义方法?如何从 __setattr__ 中调用我的自定义方法?有没有一种简单的方法可以只影响我的@property 属性而不存储要处理的属性列表?
- __getattribute__ 我尝试使用它,但最终陷入无限循环。除此之外,我的问题与 __setattr__ 大致相同,关于是否可以委托给使用 @property 声明的方法(以及如何做到这一点?),以及如何最好地说“仅适用于这些属性而不是任何属性这个类的。
解决这个问题的最佳方法是什么?
- 更新 -
详细说明:这个特定的“Bundle”类充当代理,将配置值存储在不同的后端 - 在本例中是包装 ConfigParser 的 FileConfigBackend。ConfigParser 使用 '%' 符号进行插值。但是,我想设置的一些值可以合法地包含百分号,所以我需要转义它们。但是,我不想为每个属性显式转义它们,而是希望有某种魔术方法,每次设置属性时都会调用它。然后它将replace('%', '%%')
在字符串上运行。同样,我想要一种方法,每次检索属性时,都会replace('%%', '%')
在返回值之前运行该值。
此外,由于 'Bundle' 中的大多数属性只是简单地代理到后端存储,因此如果有办法说'如果该属性在此列表中,则调用self.storage.PROPERTY_NAME = VALUE
'会很好。有时虽然我希望能够覆盖该分配,例如对要设置的值运行正则表达式。
所以真的,我正在寻找一种方式来表达'当一个属性被设置时,总是调用这个方法。然后,如果存在具体的 @property.setter,请调用它而不是执行self.storage.key = value
'.
(哦!我的意思是 __getattr__ 和 __setattr__ 不是 __get__ 和 __set__ - 更新了我的问题以反映这一点)