Python中修饰函数和方法的行为差异

2024-05-13 09:43:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我对“Pythonic static variables”使用以下解决方法:

def static_vars(**kwargs):
    """decorator for funciotns that sets static variables"""
    def decorate(func):
        for k, v in kwargs.items():
            setattr(func, k, v)
        return func
    return decorate

@static_vars(var=1)
def global_foo():
    _ = global_foo
    print _.var
    _.var += 1

global_foo()  # >>> 1
global_foo()  # >>> 2

它的工作原理和预期的一样。但当我在类中移动这样一个修饰函数时,我得到了一个奇怪的变化:

class A(object):
    @static_vars(var=1)
    def foo(self):
        bound = self.foo
        unbound = A.foo
        print bound.var  # OK, print 1 at first call
        bound.var += 1   # AttributeError: 'instancemethod' object has no attribute 'var'

    def check(self):
        bound = self.foo
        unbound = A.foo
        print 'var' in dir(bound)
        print 'var' in dir(unbound)
        print bound.var is unbound.var  # it doesn't make much sense but anyway

a = A()
a.check()  # >>> True
           # >>> True
           # >>> True

a.foo()    # ERROR

我看不出是什么导致了这种行为。在我看来,它似乎与python描述符协议有关,所有绑定与未绑定方法的东西。不知何故,foo.var属性是可访问的,但不可写。你知道吗

感谢您的帮助。你知道吗

另外,我知道静态函数变量本质上是类变量,在第二种情况下,这个修饰符是不必要的,但是问题更多的是为了理解Python,而不是为了得到任何有效的解决方案。你知道吗


Tags: 方法inselftruefoovardefstatic
1条回答
网友
1楼 · 发布于 2024-05-13 09:43:37

a.foo不返回您定义的实际函数;它返回该函数的绑定方法,该方法包装函数并将self分配给a。你知道吗

https://docs.python.org/3/howto/descriptor.html#functions-and-methods

不过,该指南有点过时了,因为未绑定方法只返回python3中的函数。你知道吗

因此,要访问函数的属性,需要通过A.foo(或a.foo.__func__)而不是a.foo。这只适用于python3。在python2中,我认为A.foo.__func__可以工作。你知道吗

相关问题 更多 >