我正在做一个项目,我需要检查设置的值是否是一组特定值的一部分。对一大堆属性需要进行完全相同的检查,所以我想设置某种模板函数,只要设置了任何一个就可以调用它。我考虑过使用 @property 装饰器,但这需要大量重复代码,而且非常冗长。所以,我想出了一个方法来使用 python 的属性函数和一些返回函数的函数:
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 函数,它可以用作所有这些属性的模板。
我的问题是:
- 这看起来是解决这个问题的合理方法吗?
- 有没有更好的方法在 python 中解决这个问题?
- 我需要注意任何副作用吗?
最佳答案
尝试使用 __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)
的原因。
关于python - 如何创建用于在 python 中设置对象属性的模板函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54813272/