当前位置: 首页 > 知识库问答 >
问题:

在decorator的包装中访问kwargs和args

潘星阑
2023-03-14

我有一个基于类的装饰器。问题是,我需要能够访问包装函数args和kwargs,但现在我不能,我不明白为什么。这应该很容易,但对我来说不是。

class limit:
    def __call__(self, fn):
        @wraps(fn)
        # the idea to use signature like (request, *args, **kwargs) is bad. I must accept *args and **kwargs only 
        def wrapper(*args, **kwargs):
             # pdb breakpoint is here
             user = kwargs.get('user') or kwargs.get('request').user // ERROR

             return fn(*args, **kwargs)

        return wrapper

让我们看看pdb。这太疯狂了。

(Pdb) args
args = (<User: dua>,)
kwargs = {}
(Pdb) kwargs
{}
(Pdb) args.args
args = (<User: dua>,)
kwargs = {}
(Pdb) args.args.args.args
args = (<User: dua>,)
kwargs = {}
(Pdb) args.get('user')
args = (<User: dua>,)
kwargs = {}
(Pdb) type(args)
<class 'tuple'>
(Pdb) 

问题是如何访问args、kwargs,并将args视为list,将kwargs视为dict。

P. S.我不知道为什么它看起来像那样。为什么它们看起来像那样?

正如在回答args中提到的,是pdb命令。用户repr(args)查看args。

下一个问题是函数的可能签名:1)def fn(请求,…)2)def fn(自身、a、b、c等,用户)3)def fn(用户)

有没有办法用一个装修师来处理所有这些问题?

共有2个答案

闻人树
2023-03-14

我最终得到了这个解决方案:

def wrapper(*args, **kwargs):
    user = None
    fn_signature_args = inspect.getfullargspec(fn).args
    # looking for a user in kwargs
    if 'user' in kwargs:
    user = kwargs['user']
    # looking for a user as positional argument
    elif 'user' in fn_signature_args:
    index = fn_signature_args.index('user')
    user = args[index]
    # looking for a user as self or request attribute
    elif fn_signature_args[0] in ('request', 'self'):
    user = args[0].user
隆睿
2023-03-14

您的pdb输出并不真正相关,这里的args就像交互式pdb命令。

为了简单起见,可以使用repr(args)或临时重命名*args参数

 类似资料:
  • 我突然在我的项目中遇到了这样的问题。重复了一遍,我的Chrome崩溃了: 因此,我降级了我的一些包,我把我的npm降级到6.6.0,这对我的项目来说是稳定的。主要的问题是从那以后开始的。我删除了node_modules文件夹,当我尝试时[因为显示权限问题],它开始显示以下错误: npm信息如果它以ok结束,则它可以工作npm谓词cli['/usr/bin/node',npm谓词cli'/data/

  • 装饰器是一种特殊类型的声明,它能够附加到类声明、方法、访问符、属性、类方法的参数上,以达到扩展类的行为。 自从 ES2015 引入 class,当我们需要在多个不同的类之间共享或者扩展一些方法或行为的时候,代码会变得错综复杂,极其不优雅,这也是装饰器被提出的一个很重要的原因。 1. 慕课解释 常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器。 装饰器的写法:普通装饰器(无法传参)、 装

  • 问题内容: 我有两个变量,范围是: 现在,由于我的应用程序的大小开始增加,因此我决定将网站的每个模块放入其自己的程序包中,就像子目录一样: 我该如何解决从其他软件包访问和全局变量的问题?这是错误的做法吗?我有一种感觉。 在这种情况下,我怎么会在声明自己的命名空间功能,所以我没有发疯具有固定其名称和所有的时间。 问题答案: 大写的变量名导出为其他包访问,因此并会工作。但是,一般不建议使用子包进行名称

  • 装饰者模式可以动态的给指定的类添加一些行为和职责,而不用对原代码进行任何修改。当你需要使用子类的时候,不妨考虑一下装饰者模式,可以在原始类上面封装一层。 在 Swift 里,有两种方式实现装饰者模式:扩展 (Extension) 和委托 (Delegation)。

  • 装饰器模式允许用户在不改变其结构的情况下向现有对象添加新功能。 这种类型的设计模式属于结构模式,因为此模式充当现有类的包装器。 此模式创建一个装饰器类,它包装原始类并提供其他功能,使类方法签名保持不变。 我们通过以下示例演示装饰器模式的使用,其中我们将使用一些颜色装饰一个没有改变形状类的形状。 实现 (Implementation) 我们将创建一个Shape接口和实现Shape接口的具体类。 然后

  • 问题内容: 我正在尝试使用具有抽象基类的Python类型注释来编写一些接口。有没有一种方法来注释可能的类型和? 例如,如何表达一个函数的明智参数是一个或两个?给出,所以我的猜测是将类型注释为,但这是行不通的。 来自mypy的错误消息: Mypy不喜欢此函数调用是有道理的,因为它希望调用本身中包含a。解压后的附加内容还会产生我不理解的输入错误。 一个人如何诠释明智的类型和? 问题答案: 对于可变位置