如何创建用于在python中设置对象属性的模板函数?

时间:2019-02-21 17:50:38

标签: python

我正在一个项目中,需要检查设置的值是否属于特定值集的一部分。整个属性都需要进行完全相同的检查,因此我想设置某种模板函数,只要设置了其中的任何一个,就可以调用它们。我看着使用@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函数,该函数可用作所有这些属性的模板。

我的问题是:

  1. 这似乎是解决这个问题的合理方法吗?
  2. 是否有更好的方法在python中解决此问题?
  3. 我需要注意任何副作用吗?

1 个答案:

答案 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)的原因。