Python 作为decorator参数访问类属性

Python 作为decorator参数访问类属性,python,class,decorator,Python,Class,Decorator,我正在尝试应用另一个stackoverflow帖子中描述的,但我希望从所使用的类内部设置条件。相反,我得到一个引用错误,指出self没有定义 class foo: def __init__(self): self.debug = True @conditional_decorator(decorator, self.debug) def function(self): pass 我尝试定义一个全局变量并从\uuuu init\uuuu(

我正在尝试应用另一个stackoverflow帖子中描述的,但我希望从所使用的类内部设置条件。相反,我得到一个引用错误,指出self没有定义

class foo:
    def __init__(self):
        self.debug = True

    @conditional_decorator(decorator, self.debug)
    def function(self):
        pass
我尝试定义一个全局变量并从\uuuu init\uuuu()方法内部更新它,但当作为装饰器的参数调用时,它保留了其原始值

debug = None

class foo:
    def __init__(self):
        self.debug = True
        global debug
        debug = self.debug

    @conditional_decorator(decorator, debug)
    def function(self):
        pass
它工作的唯一方式是声明一个全局变量并将其设置在类之外

如何将class属性的值应用于decorator


这就是让装饰器处理类和参数的方式:

from functools import wraps


def conditional_decorator(param):
    def real_decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kw):
            cls = args[0]
            print(cls.debug)
            print(param)
        return wrapper
    return real_decorator


class foo:
    def __init__(self):
        self.debug = True

    @conditional_decorator('param1')
    def function(self):
        pass



f = foo()
f.function()
输出:

True
param1

这就是让装饰器处理类和参数的方式:

from functools import wraps


def conditional_decorator(param):
    def real_decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kw):
            cls = args[0]
            print(cls.debug)
            print(param)
        return wrapper
    return real_decorator


class foo:
    def __init__(self):
        self.debug = True

    @conditional_decorator('param1')
    def function(self):
        pass



f = foo()
f.function()
输出:

True
param1

更新@Maurice Meyer给出的答案,允许提名班级成员:

from functools import wraps

def conditional_decorator(decoration, member):
    def decorator(method):
        predecorated = decoration(method)
        @wraps(method)
        def wrapper(*args, **kwargs):
            self = args[0]
            condition = getattr(self, member)
            if not condition:
                return method(*args, **kwargs)
            return predecorated(*args, **kwargs)
         return wrapper
    return decorator

#And used like this for example:
class foo:
    def __init__(self, debug):
        self.debug = debug

    @conditional_decorator(decorator, "debug")
    def function(self):
        pass

f1 = foo(True)
f1.function()

更新@Maurice Meyer给出的答案,允许提名班级成员:

from functools import wraps

def conditional_decorator(decoration, member):
    def decorator(method):
        predecorated = decoration(method)
        @wraps(method)
        def wrapper(*args, **kwargs):
            self = args[0]
            condition = getattr(self, member)
            if not condition:
                return method(*args, **kwargs)
            return predecorated(*args, **kwargs)
         return wrapper
    return decorator

#And used like this for example:
class foo:
    def __init__(self, debug):
        self.debug = debug

    @conditional_decorator(decorator, "debug")
    def function(self):
        pass

f1 = foo(True)
f1.function()

装饰者不应该是有条件的。相反,当调用修饰函数时,它应该查看
self.debug
,以确定是使用原始函数还是使用包装的部分

def conditional_decorator(dec):
    def decorator(func):
        def _(self, *args, **kwargs):
            f = func
            if self.debug:
                f = dec(f)
            return f(self, *args, **kwargs)
        return _
    return decorator


def decorator(f):
    def _(*args, **kwargs):
        print("Decorated")
        return f(*args, **kwargs)
    return _


class foo:
    def __init__(self, debug):
        self.debug = debug

    @conditional_decorator(decorator)
    def function(self):
        print("foo stuff")

foo(True).function()
print("===")
foo(False).function()
输出

Decorated
foo stuff
===
foo stuff

装饰者不应该是有条件的。相反,当调用修饰函数时,它应该查看
self.debug
,以确定是使用原始函数还是使用包装的部分

def conditional_decorator(dec):
    def decorator(func):
        def _(self, *args, **kwargs):
            f = func
            if self.debug:
                f = dec(f)
            return f(self, *args, **kwargs)
        return _
    return decorator


def decorator(f):
    def _(*args, **kwargs):
        print("Decorated")
        return f(*args, **kwargs)
    return _


class foo:
    def __init__(self, debug):
        self.debug = debug

    @conditional_decorator(decorator)
    def function(self):
        print("foo stuff")

foo(True).function()
print("===")
foo(False).function()
输出

Decorated
foo stuff
===
foo stuff

顺便说一句,修饰符是在python读取程序文本时应用的,而不是在运行时应用的。@quamrana:不,修饰符是在函数定义时应用的。好的,函数定义时间是什么时候?python函数定义是必需的-执行一个函数定义会生成一个新的函数对象。装饰器在这一点之后立即应用。当Python读取源代码时,它们不是也不能应用;此时没有要传递给decorator的函数对象,也可能没有要调用的decorator。但肯定的是,在python读取源代码时(是的,在读取整个函数之后),每个函数都会出现函数定义时间,否则类可以通过名称来引用自己。顺便说一句,修饰符是在python读取程序文本时应用的,而不是在运行时应用的。@quamrana:不,修饰符是在函数定义时应用的。好的,函数定义时间是什么时候?python函数定义是必需的-执行一个修饰符会生成一个新的函数对象。装饰器在这一点之后立即应用。当Python读取源代码时,它们不是也不能应用;此时没有要传递给decorator的函数对象,也可能没有要调用的decorator。但肯定的是,在python读取源代码时(是的,就在读取整个函数之后),每个函数都会有函数定义时间,否则类可以通过名称来引用自己。