python - Python如何解析装饰器名称

标签 python decorator python-decorators

我有以下代码:

import threading
from functools import wraps
class Synchronized(object):
    def __init__(self):
        self.lock = threading.Lock()

    def synchronized(f):
        @wraps(f)
        def wrapper(self, *args, **kwargs):
            with self.lock:
                print "here"
                return f(self, *args, **kwargs)
        return wrapper

    @synchronized
    def go(self):
        print 1

class B(Synchronized):
    @synchronized
    def foo(self):
        return 1

此代码在导入提示时失败:

  File "a.py", line XXX, in B
    @synchronized
NameError: name 'synchronized' is not defined

但是,如果我注释掉 B 并只使用 Syncrhonized().go(),效果会很好。

问题: python 如何知道基类中的@synchronized 是什么,但在派生类中无法解析?

最佳答案

synchronized 被定义为 Synchronized 类主体中的一个函数

类体像定义类的函数一样被执行;生成的本地 namespace 用于形成类属性。这就是为什么 synchronizedgo 上用作装饰器时仍然是 Synchronized 中的局部名称。您可以将其与在函数内部定义装饰器,然后尝试在该函数的外部 应用它进行比较;它不会起作用,因为装饰器是局部变量。

您可以在 B 类中使用 @Syncronized.synchronized.im_func(.im_func 从方法包装器中解包函数):

class B(Synchronized):
    @Synchronized.synchronized.im_func
    def foo(self):
        return 1

更好的是,根本 不在类内部定义装饰器,而是在 Synchronized外部 定义装饰器。毕竟,这不是一种方法:

def synchronized(f):
    @wraps(f)
    def wrapper(self, *args, **kwargs):
        with self.lock:
            print "here"
            return f(self, *args, **kwargs)
    return wrapper

class Synchronized(object):
    def __init__(self):
        self.lock = threading.Lock()

    @synchronized
    def go(self):
        print 1

class B(Synchronized):
    @synchronized
    def foo(self):
        return 1

关于python - Python如何解析装饰器名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17811213/

相关文章:

python - 如何修复 'pygame.error: Couldn' t 打开 .png' 错误

python - 使用装饰器更新包装器时遇到错误

php - Zend Framework 2 - 表单元素装饰器

python - 了解装饰器

Python 装饰器使用静态方法。但是使用 2 个静态方法失败。为什么?

python - 在python中获取属性的属性

python - 与 RPi 成功建立蓝牙连接

python - 使范围内的所有值显示在 x 轴上

python - 试图将大量数据输入 mysqldb

java - 向任何 java 异常添加属性