Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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 3.x_Decorator_Python Decorators - Fatal编程技术网

Python 比较包装函数是否为装饰器实例

Python 比较包装函数是否为装饰器实例,python,python-3.x,decorator,python-decorators,Python,Python 3.x,Decorator,Python Decorators,我有decorator1和decorator2功能。我用这些来装饰一个功能 @decorator1("some", "args") @decorator2(1,2) @decorator1() def my_func(): print("my func") 当我反复调用包装函数时,输出如下: 对于my\u func.\uuuuuu wrapped\uuuu: decorator1 decorator2 decorator1 my func decorator2 decorator1 my f

我有
decorator1
decorator2
功能。我用这些来装饰一个功能

@decorator1("some", "args")
@decorator2(1,2)
@decorator1()
def my_func(): print("my func")
当我反复调用包装函数时,输出如下:

对于
my\u func.\uuuuuu wrapped\uuuu

decorator1
decorator2
decorator1
my func
decorator2
decorator1
my func
对于
my\u func.\uuuuuu wrapped\uuuuuu()

问题是每个包装函数的名称都是
myfunc
。我想检查这个链中的函数是否是的实例,比如说
decorator1
。我想知道这一点,因为我将使用装饰器的参数。(我已经通过使用
\uuuuu closure\uuuu
单元格了解了它们。)

澄清

我决定举个例子来说明我的目的

@route("/index")
def index(): pass

@route("/settings")
@need_permission("admin")
def settings: pass

@route("/blog")
@need_permission("admin", "user")
def blog(): pass
我可以在其他地方获得所有这些路由函数,我想提取哪个需要哪些权限

以下是我的发现:

>>> blog()
route blog
permissions admin user
>>> blog.__closure__[0].cell_contents
('/blog',)
>>> blog.__closure__[1].cell_contents()
permissions admin user
>>> blog.__closure__[0].cell_contents.__closure__[0].cell_contents
('admin', 'user')
>>> blog.__closure__[0].cell_contents.__closure__[1].cell_contents()
>>> 

我只想提取拥有权限的元组。我可以按照特定的顺序应用我的decorator并轻松提取,或者我需要实现@Poolka指出的
DecoratorApplier
函数。如果没有办法像第一个选项那样知道,我将遵循第二个选项。

装饰器的实例
-用函数和常规函数实现的装饰器都只是
函数
类型的函数

不知道你到底想要什么。下面的代码是我如何处理这个问题的。基本上,我将属性
primal_type
添加到装饰嘉年华中涉及的所有函数中,以存储函数/装饰器的名称。我使用另一个名为
DecoratorApplier
的装饰器来完成这项工作。代码似乎执行了与问题中的问题相关的操作

编辑

补充的澄清并没有把一切都说清楚。我想以这种方式混合函数和装饰逻辑是不好的做法。也许还有另一个选项可以在函数中获取所需的信息?无论如何,下面是我最初方法的两个修改版本(
oda
代表可选的装饰参数)

(1) -带有装饰应用程序

import functools


def decorator_1(*d1_args, **d1_kwargs):
    def decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            print('inside decorator_1', d1_args, d1_kwargs)
            return func(*args, **kwargs)
        return wrapped
    return decorator


def decorator_2(*d2_args, **d2_kwargs):
    def decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            print('inside decorator_2', d2_args, d2_kwargs)
            return func(*args, **kwargs)
        return wrapped
    return decorator


class DecoratorApplier:

    def __init__(self, *decorators):
        self.decorators = decorators

    def __call__(self, func):
        func.oda = dict()
        for decorator in self.decorators:
            func = decorator[0](*decorator[1], **decorator[2])(func)
            (
                func
                .oda
                .setdefault(decorator[0].__name__, list())
                .extend([decorator[1], decorator[2]])
            )
        return func


@DecoratorApplier(
    (decorator_1, (1, 2), {'x': 10, 'y': 20}),
    (decorator_2, tuple(), dict()))
def f_1():
    print('inside f_1')
    print(f_1.oda)
    return


if __name__ == '__main__':

    f_1()
(2) -通过修改原始装饰器

import functools


def decorator_1(*d1_args, **d1_kwargs):
    def decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            print('inside decorator_1', d1_args, d1_kwargs)
            (
                kwargs
                .setdefault('oda', dict())
                .setdefault('decorator_1', list())
                .extend([d1_args, d1_kwargs])
            )
            return func(*args, **kwargs)
        return wrapped
    return decorator


def decorator_2(*d2_args, **d2_kwargs):
    def decorator(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            print('inside decorator_2', d2_args, d2_kwargs)
            (
                kwargs
                .setdefault('oda', dict())
                .setdefault('decorator_2', list())
                .extend([d2_args, d2_kwargs])
            )
            return func(*args, **kwargs)
        return wrapped
    return decorator


@decorator_1(1, 2, x=10, y=20)
@decorator_2()
def f_1(oda=None):
    print('inside f_1')
    print('    oda', oda)
    return


if __name__ == '__main__':

    f_1()

你需要提供更多关于装饰师的细节。
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
属性是由装饰器定义中的某些东西添加的,而不仅仅是通过装饰函数的行为添加的;这只是定义my_func()的快捷方式:。。。;my_func=decorator1(“some”,“args”)(decorator2(1,2)(decorator1()(my_func))。请注意,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>可能是由
functools.wrapps添加的。wrapps
,其目的是使被包装。看,是的,我知道装修工是怎么工作的,但我想可能还有别的办法。我还添加了一个澄清。@maydin我稍微修改了答案。不确定这是否是合理的解决方案。也许有别的方法可以得到这些信息?