我正在一个项目中,需要检查设置的值是否属于特定值集的一部分。整个属性都需要进行完全相同的检查,因此我想设置某种模板函数,只要设置了其中的任何一个,就可以调用它们。我看着使用@property装饰器,但这将需要大量重复的代码,并且非常冗长。因此,我想出了一种使用python的property函数和一些返回函数的函数来实现此目的的方法:
class MyClass(object):
style_types = ("FOO", "BAR", "NONE")
def __init__(self):
self._style_a = "NONE"
self._style_b = "NONE"
self.name = None
def get_tmpl(attr):
def get_attr(self):
return getattr(self, attr)
return get_attr
def set_tmpl(attr):
def set_attr(self, val):
if val.upper() in style_types:
setattr(self, attr, val.upper())
else:
setattr(self, attr, "NONE")
return set_attr
def del_tmpl(attr):
def del_attr(self):
delattr(self,attr)
return del_attr
style_a = property( get_tmpl("_style_a"), set_tmpl("_style_a"), del_tmpl("_style_a") )
style_b = property( get_tmpl("_style_b"), set_tmpl("_style_b"), del_tmpl("_style_b") )
输入:
c = MyClass()
print "style_a = " + c.style_a + ", style_b = " + c.style_b
c.style_a = "FOO"
c.style_b = "bad"
print "style_a = " + c.style_a + ", style_b = " + c.style_b
输出:
style_a = NONE, style_b = NONE
style_a = FOO, style_b = NONE
因此,基本上,我正在创建一些函数,这些函数返回函数并传递应在其上使用的属性。然后,我可以构建一个通用的set_attr函数,该函数可用作所有这些属性的模板。
我的问题是:
答案 0 :(得分:1)
尝试使用__setattr__
。它比返回函数的函数少魔术,看起来更易读,恕我直言。这是用__setattr__
class MyClass(object):
style_types = ("FOO", "BAR", "NONE")
def __init__(self):
self.style_a = "NONE"
self.style_b = "NONE"
self.not_style_c = "bad"
def __setattr__(self, name, value):
if name.startswith('style'):
if value.upper() in self.style_types:
object.__setattr__(self, name, value.upper())
else:
object.__setattr__(self, name, "NONE")
else:
object.__setattr__(self, name, value)
c = MyClass()
print("style_a = " + c.style_a + ", style_b = " + c.style_b + ", not_style_c = " + c.not_style_c)
c.style_a = "FOO"
c.style_b = "bad"
c.not_style_c = "good"
print("style_a = " + c.style_a + ", style_b = " + c.style_b + ", not_style_c = " + c.not_style_c)
副作用:请谨慎使用setattr
中的__setattr__
,您可能会陷入无限递归。这就是使用object.__setattr__(self, name, value)
的原因。