如何在Python中自动公开和修饰方法的函数版本?

时间:2012-02-29 19:26:07

标签: python function methods functional-programming vectorization

我想在我的本地范围中将类的方法公开为函数(装饰后)。例如,如果我有一个类和装饰器:

def some_decorator(f):
    ...transform f...
    return decorated_f

class C(object):
    def __init__(self,x):
        self.x = x
    def f(self,y):
        "Some doc string"
        return self.x + y
    def g(self,y,z):
        "Some other doc string"
        return self.x + y + z

如果我不关心自动化过程,我可以将以下代码添加到我的模块中:

@some_decorator
def f(C_instance,x):
    "Some doc string."
    return C_instance.f(x)

@some_decorator
def g(C_instance,x,y):
    "Some other doc string."
    return C_instance.g(x,y)    

表示以下评估为True

c = C(0)
f(c,1) == c.f(1)

但我希望能够自动完成此操作。类似的东西:

my_funs = expose_methods(MyClass)
for funname, fun in my_funs.iteritems():
    locals()[funname] = some_decorator(fun)

foo = MyClass(data)
some_functionality(foo,*args) == foo.some_functionality(*args)

可以做到这一点(虽然以这种方式声明局部变量感觉有点不对劲)。如何以某种方式执行此操作,以便方法的所有相关属性正确转换为函数版本?我很感激任何建议。

P.S。

我知道我可以装饰类实例的方法,但这不是我所追求的。它更多地是关于(1)对函数版本语法的偏好(2)我的装饰器使函数以奇特和优化的方式映射到对象集合的事实。通过修饰方法来获取行为(2)需要我的集合类从它们包含的对象继承属性,这与集合语义正交。

2 个答案:

答案 0 :(得分:3)

您是否知道可以直接使用未绑定的方法?

obj.foo(arg)相当于ObjClass.foo(obj, arg)

class MyClass(object):
    def foo(self, arg):
        ...

obj = MyClass()
print obj.foo(3) == MyClass.foo(obj, 3) # True

另请参阅Class method differences in Python: bound, unbound and staticdocumentation

答案 1 :(得分:0)

您说您偏好函数语法。您可以在课堂外定义所有方法,它们可以完全按照您的意愿工作。

class C(object):
    def __init__(self,x):
        self.x = x

def f(c,y):
    "Some doc string"
    return c.x + y
def g(c,y,z):
    "Some other doc string"
    return c.x + y + z

如果你也希望他们上课,你可以随时:

for func in f, g:
    setattr(C, func.__name__, func)

或者使用本地内省而不是函数名称内省:

for name in 'f', 'g':
    setattr(C, name, locals()[name])

或者没有内省,除非你有很多这些方法/功能,否则它可以说更简单,更容易管理:

C.f = f
C.g = g

这也避免了关于codeape关于Python检查的问题的评论中提到的潜在问题,即未绑定方法的第一个参数是该类的实例。