【问题标题】:How to build a method generator to create similar class methods如何构建方法生成器以创建类似的类方法
【发布时间】:2018-01-04 16:04:59
【问题描述】:

例如:

class person():
    def __init__(self):
        self.a1 = 0
        self.a2 = 0
        self.a3 = 0

    def method_a1(self):
        self.a1 = self.a1 * 2
        print(self.a1)

    def method_a2(self):
        self.a2 = self.a2 * 2
        print(self.a2)

    def method_a3(self):
        self.a3 = self.a3 * 2
        print(self.a3)

这三个方法是相似的,所以我想构建一个函数来生成这些方法,像这样:

class person():
    def __init__(self):
        self.a1 = 0
        self.a2 = 0
        self.a3 = 0

   def method(p):
       p = p * 2
       print(p)

   method(self.a1)
   method(self.a2)
   method(self.a3)

我不知道怎么写。

【问题讨论】:

    标签: python class


    【解决方案1】:

    你可以按照以下方式做某事:

    def _helper(attr):
        def method(self):
            val = getattr(self, attr) * 2
            setattr(self, attr, val)
            print(val)
        return method
    
    class person():
        # ...
        method_a1 = _helper('a1')
        method_a2 = _helper('a2')
        method_a3 = _helper('a3')
    

    【讨论】:

    • 觉得这是最好的呈现方式。实际上是创建类方法(实际上有self)而不是空函数的属性。
    • 是的,对于大多数目的来说效果是相同的,但是你只为类创建了一次函数对象(类方法可能不是正确的术语,因为它已经用于其他用途)和不是每个实例。如果您不必挂钩__init__,它也会更优雅一点。
    【解决方案2】:

    您可以直接在__init__ 中分配它们,并使用一些通用函数通过getattr()setattr() 的字符串检索属性,并返回要调用的函数:

    class person():
        def __init__(self):
            self.a1 = 0
            self.a2 = 0
            self.a3 = 0
    
            self.method_a1 = self._generic_update('a1')
            self.method_a2 = self._generic_update('a2')
            self.method_a3 = self._generic_update('a3')
    
        def _generic_update(self, attribute):
            def update():
                value = getattr(self, attribute)
                setattr(self, attribute, value * 2)
                print(getattr(self, attribute)
            return update
    

    【讨论】:

    • 我比我的答案更喜欢这个:-D(特别是因为分配给method_a1method_a2)...
    • 虽然你是对的,但任何情况下你必须开始退出getattrsetattr,事情就会开始变得混乱。作为最后的手段使用。
    【解决方案3】:

    你可以用 Python 做很多奇怪的事情。

    想到的是使用getattr(从表示其名称的字符串中获取属性)和setattr(使用其名称编写属性)

    看看这个:

    class Person(object):
        def __init__(self):
            self.a1 = 0
            self.a2 = 1
            self.a3 = 2
    
        def method(self, attr_name):
            new_value = getattr(self, attr_name) * 2
            setattr(self, attr_name, new_value)
            print(getattr(self, attr_name))
    
    
    if __name__ == "__main__":
        pers = Person()
        pers.method('a1')
        pers.method('a2')
        pers.method('a3')
    

    输出:

    0
    2
    4
    

    但是:您还应该考虑可读性:有时多写一点可以让阅读您的代码的其他人更好地理解它。滥用这样的事情会使代码非常混乱非常快。

    【讨论】:

      猜你喜欢
      • 2020-09-08
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2021-01-03
      • 2013-08-31
      • 1970-01-01
      相关资源
      最近更新 更多