Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 条件装饰器实现_Python_Python Decorators - Fatal编程技术网

Python 条件装饰器实现

Python 条件装饰器实现,python,python-decorators,Python,Python Decorators,我想要一个有条件的装饰师。以下是我的代码:- def int_decorator(func): # checks whether the args passed is of type int. def wrapper(*args, **kwargs): a, b = args if not (isinstance(a, int) and isinstance(b, int)): return return func

我想要一个有条件的装饰师。以下是我的代码:-

def int_decorator(func):  # checks whether the args passed is of type int.
    def wrapper(*args, **kwargs):
        a, b = args
        if not (isinstance(a, int) and isinstance(b, int)):
            return
        return func(*args, **kwargs)
    return wrapper


decorator_mapping = {
    'int': int_decorator
}

class conditional_decorator(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        decorator = decorator_mapping.get(kwargs.get('decorator'))
        if not decorator:
            # Return the function unchanged, not decorated.
            return self.func(*args, **kwargs)
        return decorator(self.func(*args, **kwargs))


@conditional_decorator
def func(a, b, *args, **kwargs):
    return(1)

print(func(1, 2, decorator='int'))
我想要的是,如果
decorator\u mapping
中存在任何与
func
中传递的值匹配的decorator,则对函数应用相同的decorator,否则不要应用任何decorator

当没有代码时,上面的代码工作得很好;没有任何装饰程序,但在找到装饰程序时失败。它是
函数
的参考

我错在哪里

def __call__(self, *args, **kwargs):
    decorator = decorator_mapping.get(kwargs.get('decorator'))
    if not decorator:
        # Return the function unchanged, not decorated.
        return self.func(*args, **kwargs)
    return decorator(self.func)(*args, **kwargs)
您想要修饰函数,然后调用它的修饰版本


您希望修饰函数,然后调用它的修饰版本。

修饰器接受函数,返回函数。这一行:

    return decorator(self.func(*args, **kwargs))
应该是:

    return decorator(self.func)(*args, **kwargs)

Decorator接受一个函数,返回一个函数。这一行:

    return decorator(self.func(*args, **kwargs))
应该是:

    return decorator(self.func)(*args, **kwargs)

顺便说一句,这是一个非常低效的装饰器,因为除了至少一个额外函数调用所涉及的所有常规开销之外,它必须在每次调用目标函数时重复装饰过程,而不是在定义目标函数后仅重复一次。我建议你避免使用它,即使你现在知道它需要简单的“修复”。那么你会如何定义一个条件装饰器?@pythonenthsusist将条件分支移动到
\uuuuuu init\uuuuu
,比如
self.final\u func=decorator(func)if decorator\u mapping.get(kwargs.get('decorator'))else func
,你能正确地缩进它吗,而是把它作为一个答案。这对观众来说是非常有帮助和清晰的。PythontHusiast:提高效率取决于你的意图。按照您目前的方式,直到调用该函数,才提供实际需要的装饰器。我想从某种意义上说,这是非常动态的,但我怀疑这是否真的是必需的,这样做会带来很大的运行时开销。从一个函数调用到下一个函数调用,decorator的值会不同吗?摆脱它的一种方法是将decorator作为参数提供给
条件decorator
。这是可以接受的吗?顺便说一句,这是一个非常低效的装饰器,因为除了至少一个额外函数调用所涉及的所有常规开销之外,它必须在每次调用目标函数时重复装饰过程,而不是在定义目标函数后仅重复一次。我建议你避免使用它,即使你现在知道它需要简单的“修复”。那么你会如何定义一个条件装饰器?@pythonenthsusist将条件分支移动到
\uuuuuu init\uuuuu
,比如
self.final\u func=decorator(func)if decorator\u mapping.get(kwargs.get('decorator'))else func
,你能正确地缩进它吗,而是把它作为一个答案。这对观众来说是非常有帮助和清晰的。PythontHusiast:提高效率取决于你的意图。按照您目前的方式,直到调用该函数,才提供实际需要的装饰器。我想从某种意义上说,这是非常动态的,但我怀疑这是否真的是必需的,这样做会带来很大的运行时开销。从一个函数调用到下一个函数调用,decorator的值会不同吗?摆脱它的一种方法是将decorator作为参数提供给
条件decorator
。那可以接受吗?