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

如何在python中创建用于设置对象属性的模板函数?,python,Python,我正在进行一个项目,需要检查所设置的值是否是特定值集的一部分。对于一大堆属性,需要进行完全相同的检查,因此我想设置一些模板函数,可以在设置任何属性时调用这些函数。我考虑过使用@property decorator,但这需要大量重复代码,而且非常冗长。因此,我想出了一种方法,使用python的属性函数和一些返回函数的函数: class MyClass(object): style_types = ("FOO", "BAR", "NONE") def __init__(self):

我正在进行一个项目,需要检查所设置的值是否是特定值集的一部分。对于一大堆属性,需要进行完全相同的检查,因此我想设置一些模板函数,可以在设置任何属性时调用这些函数。我考虑过使用@property decorator,但这需要大量重复代码,而且非常冗长。因此,我想出了一种方法,使用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中有更好的方法解决这个问题吗
  • 有什么副作用我需要注意吗

  • 尝试使用
    \uuuuu setattr\uuuuu
    。imho说,它比返回函数的函数更神奇,而且看起来更可读。下面是您使用
    \uuuuu setattr\uuuuu
    编写的示例

    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)
    

    副作用:在
    \uuuu setattr\uuuu
    中小心使用
    setattr
    ,可能会陷入无限递归。这就是为什么要使用
    object.\uuuuuu setattr\uuuuu(self,name,value)

    Hmm,也许我可以用这些信息创建一个装饰器,并将要创建的属性列表传递给它,然后装饰init函数hi,我找到一个可能有用的页面。这是关于python的属性。我真的很喜欢这个。这是一种比我想做的更简单、更容易理解的方法。谢谢三亚!格拉格来帮你!