python - 装饰器参数中无法识别的类

标签 python namespaces decorator

将类变量作为装饰器函数的参数传递会导致 NameError为类名。运行这个:

def log(prefix=None):

    def decorator(function):
        """Decorates the function"""

        def wrapper(*args, **params):
            """Wraps the function"""
            name = "-".join([prefix, function.__name__])

            result = function(*args, **params)
            print(f"completed the execution of '{name}'")
            return result

        return wrapper

    return decorator
    
class ExampleClass:

    _CONSTANT = "test"

    def __init__(self, x):
        self._x = x

    @log(prefix=ExampleClass._CONSTANT)
    def product_of_number(self, y):
        return self._x * y

if __name__ == "__main__":
    x = ExampleClass(3)
    x.product_of_number(4)
导致错误
Traceback (most recent call last):
  File "/home/developer/reproduce_decorator_name_space.py", line 23, in <module>
    class ExampleClass:
  File "/home/developer/reproduce_decorator_name_space.py", line 31, in ExampleClass
    @log(prefix=ExampleClass._CONSTANT)
NameError: name 'ExampleClass' is not defined

但是,运行这个
def log(prefix=None):

    def decorator(function):
        """Decorates the function"""

        def wrapper(*args, **params):
            """Wraps the function"""
            name = "-".join([prefix, function.__name__])

            result = function(*args, **params)
            print(f"completed the execution of '{name}'")
            return result

        return wrapper

    return decorator
    
_CONSTANT = "test"
class ExampleClass:

    def __init__(self, x):
        self._x = x

    @log(prefix=_CONSTANT)
    def product_of_number(self, y):
        return self._x * y

if __name__ == "__main__":
    x = ExampleClass(3)
    x.product_of_number(4)
给出输出
completed the execution of 'test-product_of_number'
为什么是 ExampleClass未能识别?修饰方法在__init__之后的类内并引用自我。错误消息本身是指模块 ExampleClass . namespace 中如何不存在类名?

最佳答案

装饰者有权访问 ExampleClass ,可能不需要将参数传递给装饰器:

def log(prefix=''):
    def decorator(function):
        """Decorates the function"""
        def wrapper(*args, **params):
            """Wraps the function"""
            # args[0] references the decorated class

            if prefix:
                # Option2: Prefix passed as string
                name = "-".join(
                    [getattr(args[0], prefix, ''), function.__name__])
            else:
                # Option1: No prefix
                name = "-".join([args[0]._CONSTANT, function.__name__])

            result = function(*args, **params)
            print(f"completed the execution of '{name}'")
            return result

        return wrapper

    return decorator


class ExampleClass:

    _CONSTANT = "test"
    _ANOTHER_CONSTANT = "test2"

    def __init__(self, x):
        self._x = x

    @log()
    def product_of_number(self, y):
        return self._x * y

    @log('_ANOTHER_CONSTANT')
    def product_of_anothernumber(self, y):
        return self._x * y


if __name__ == "__main__":
    x = ExampleClass(3)
    x.product_of_number(4)
    x.product_of_anothernumber(4)
出去:
completed the execution of 'test-product_of_number'
completed the execution of 'test2-product_of_anothernumber'

关于python - 装饰器参数中无法识别的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70319580/

相关文章:

python - 如何有效地掩盖pygame中的表面

python - Jinja2 检查字典列表中是否存在值

python - 使用迭代变量检查字典键的值?

c# - 在两个命名空间中使用相同的类名 - 优先考虑其中之一

c++ - 跨多个文件定义命名空间

angularjs - 在 AngularJs 中装饰 ng-click 指令

c# - ninject - 使用工厂模式将通用参数传递给装饰器链

python - 如何按同一月份对这个字典列表进行分组?

.net - 在 C# 中使用内置命名空间

Python C 扩展装饰器