如何在__init__中定义与不同类属性相关的类似类函数

时间:2013-04-04 11:10:26

标签: python class

我有一个这样的课程:

class MyClass(object):

    def f_1(self,x):
        return foo(x, self.property_1)

    def f_2(self,x):
        return foo(x, self.property_2)

这个想法是多个函数f_n具有共同的结构,但依赖于类的不同属性property_n

我想找到一种更简洁的方法来定义f_n中的__init__?我想像

这样的东西
class MyClass(object):

    def __init__(self):
        self.f_1 = self.construct_function(self.property_1)
        self.f_2 = self.construct_function(self.property_2)

    def construct_function(self, property):
        # ???    

这就是我想到的,但我不知道如何定义这个construct_function。重要的是“财产”属于逐点类型。

修改

我将Martijn's very good answer简化为此解决方案,效果很好:

def construct_function(property_name):
    def f_n(self, x):
        return foo(x, getattr(self, property_name))

    return f_n

class MyClass2(object):

    f_1 = construct_function('property_1')
    f_2 = construct_function('property_2')

我想在此提及,因为不允许多行评论......

2 个答案:

答案 0 :(得分:1)

如果要为每个生成这些方法,请使用类装饰器:

def property_functions(**properties):
    def construct_method(prop):
        def f_n(self):
            return foo(getattr(self, prop))
        return f_n

    def class_decorator(cls):
        for name, prop in properties.iteritems():
            setattr(cls, name, construct_method(prop))

        return cls

    return class_decorator

然后使用它:

@property_functions(f_1='property_1', f_2='property_2')
class MyClass(object):
    property_1 = 'foo'
    property_2 = 'bar'

演示:

>>> def foo(value): print value
... 
>>> @property_functions(f_1='property_1', f_2='property_2')
... class MyClass(object):
...     property_1 = 'foo'
...     property_2 = 'bar'
... 
>>> mc = MyClass()
>>> mc.f_1()
foo
>>> mc.f_2()
bar

答案 1 :(得分:0)

您可以查看 getattr getattribute 。它们允许您动态创建和引用属性。对于前

它的工作原理如下:

class foo:
    def __init__(self):
        self.a = "a"
    def __getattr__(self, attribute):
        return "You asked for %s, but I'm giving you default" % attribute


>>> bar = foo()
>>> bar.a
'a'
>>> bar.b
"You asked for b, but I'm giving you default"
>>> getattr(bar, "a")
'a'
>>> getattr(bar, "b")
"You asked for b, but I'm giving you default"