python 是否允许我在运行时将动态变量传递给装饰器?

2023-11-25

我正在尝试在工作中集成一个非常旧的系统和一个较新的系统。我能做的最好的事情就是利用系统使用的 RSS 消防站类型提要。目标是使用此 RSS 源让其他系统在某些人做某事时执行某些操作。

我的想法是在某些函数周围封装一个装饰器来检查用户(RSS 提要中提供的用户 ID)是否在新系统中具有权限。

我当前的解决方案有很多类似这样的函数,它们是基于actionFeed 中的字段:

actions_dict = {
    ...
    'action1': function1
}

actions_dict[RSSFEED['action_taken']](RSSFEED['user_id'])

def function1(user_id):
    if has_permissions(user_id):
         # Do this function

我想创建一个has_permissions装饰器采用user_id这样我就可以删除这个多余的has_permissions检查我的每个功能。

@has_permissions(user_id)
def function1():
    # Do this function

不幸的是,我不知道如何编写这样的装饰器。我看到的所有教程都有@has_permissions()与硬编码值一致,但在我的情况下,它需要在运行时传递,并且每次调用函数时都会不同。

我怎样才能实现这个功能?


在你的问题中,你已经命名了两者,检查user_id,以及想要的装饰器has_permissions,所以我将举一个名称更清晰的示例:让我们创建一个装饰器,当颜色(字符串)为'green'.

Python 装饰器是函数工厂

装饰器本身(if_green在我下面的示例中)是一个函数。它需要一个函数来装饰作为参数(名为function在我的示例中)并返回一个函数(run_function_if_green在示例中)。通常,返回的函数在某个时刻调用传递的函数,从而用它之前或之后或两者都运行的其他操作来“装饰”它。

当然,它可能只是有条件地运行它,正如您似乎需要的那样:

def if_green(function):
    def run_function_if_green(color, *args, **kwargs):
        if color == 'green':
            return function(*args, **kwargs)
    return run_function_if_green


@if_green
def print_if_green():
    print('what a nice color!')


print_if_green('red')  # nothing happens
print_if_green('green')  # => what a nice color!

当你用装饰器装饰一个函数时会发生什么(就像我所做的那样)print_if_green,这里)是装饰器(函数工厂,if_green在我的示例中)被原始函数调用(print_if_green正如您在上面的代码中看到的那样)。正如它的本质一样,它返回一个不同的函数。那么Pythonreplaces原始函数与装饰器返回的函数。

所以在后续的调用中,它是返回的函数(run_function_if_green与原来的print_if_green as function)被称为print_if_green并且有条件地进一步调用原始的print_if_green.

函数工厂可以生成带参数的函数

对装饰器的调用(if_green) 对于每个修饰函数仅发生一次,而不是每次调用修饰函数时发生。但随着函数returned由装饰者一次性永久地replaces原始函数,每次调用原始函数时都会调用它而不是原始函数。如果我们允许的话,它可以接受争论。

我已经给了它一个论点color,它使用自身来决定是否调用装饰函数。此外,我给了它惯用的 vararg 参数,它用它来调用包装函数(如果它调用它),这样我就可以使用任意数量的位置参数和关键字参数来装饰函数:

@if_green                     
def exclaim_if_green(exclamation):
    print(exclamation, 'that IS a nice color!')

exclaim_if_green('red', 'Yay')  # again, nothing
exclaim_if_green('green', 'Wow')  # => Wow that IS a nice color!

装饰函数的结果if_green是一个新的第一个参数被添加到其签名之前,这对于原始函数来说是不可见的(如run_function_if_green不转发)。由于您可以自由地实现装饰器返回的函数,因此它还可以使用更少、更多或不同的参数调用原始函数,在将它们传递给原始函数之前对它们进行任何所需的转换或执行其他疯狂的操作。

概念、概念、概念

了解装饰器需要了解和理解 Python 语言的各种其他概念。 (其中大多数不是 Python 特有的,但人们可能仍然不知道它们。)

为了简洁起见(这个答案已经足够长了),我跳过或掩盖了其中的大多数。为了更全面地快速浏览(我认为)所有相关的内容,请参阅例如通过 12 个简单步骤了解 Python 装饰器!.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python 是否允许我在运行时将动态变量传递给装饰器? 的相关文章

随机推荐

  • C++ 类中对象计数的静态变量?

    我希望有一个静态成员变量来跟踪已创建的对象的数量 就像这样 class test static int count 0 public test count 这是行不通的 因为根据 VC 的说法 a member with an in cla
  • python 3.5 asyncio和aiohttp Errno 101网络无法访问

    我在 Ubuntu 16 上使用 python 3 5 我正在尝试使用 aiohttp 编写一个简单的客户端 这是我的代码 我把它从here 这是第一个代码示例 禁用了 ssl 检查 import aiohttp import asynci
  • 如何使单词边界 \b 与破折号不匹配

    我将代码简化为我遇到的具体问题 import re pattern re compile r bword b result pattern sub lambda x match word word 我正进入 状态 match match 但
  • 从屏幕中心获取位置 Swift MapKit

    我是 Swift 编程新手 我正在尝试构建一个应用程序 我可以使用 MapKit 和 Swift 2 获取视图中心的坐标 我已经可以获得当前位置 但如果我在地图上移动 我需要将位置设置为新点 该点将成为屏幕的中心 你能帮我解决这个问题吗 R
  • Swift 将每隔一个项目追加到数组中

    我有一个快速数组 Monthdata 我想将每个第二个值附加到我的月份数组中 var monthData let months Jul 12 Aug 12 Sep 12 Oct 12 for month in months self mon
  • 离开作用域时调用函数

    离开作用域时自动调用函数的最优雅的解决方案是什么 我目前的方法 见下文 works但我想应该有一些更通用的东西 比如为此编写一个自定义类 include
  • 为什么函数需要在定义或使用之前声明?

    在 C 中它是可选的 在C 中一 MUST 在使用 定义函数之前声明它 为什么会这样呢 有什么需要吗 我们不会在 C 或 Java 中这样做 有趣的是当我们在的时候defining一个函数 即使定义本身有一个声明 我们也需要声明 天知道为什
  • ActionScript 中的语法突出显示库

    我让用户在我的 Flex3 Flash 10 应用程序中输入一些代码 我想进行语法突出显示 有没有开源库可以帮助我 我需要 Lua 语法支持 但如果库有一个合理的接口来执行此操作 我可以自己添加它 2009 年 1 月 21 日更新 查看A
  • 如何本地化 Django 应用程序的内容

    嘿 我目前正在为我的学习开发一个 django 应用程序 并且已经到了 l18n 的地步 本地化网站本身非常容易 但现在我必须允许用户翻译应用程序的动态内容 用户可以将 产品 保存在数据库中并为其提供名称和描述 但由于整个站点应该本地化 因
  • R 在 Mac OS X Yosemite 中冻结

    我遇到了这个问题 并且没有关于如何解决这个错误的明确解释 每当我尝试保存使用 R 内部编辑器编写的文件时 OS X Mavericks 的最新版本 R v 3 1 2 就会在 Yosemite 中冻结 当您尝试时它也会冻结source一个函
  • 将 URL 解码为数组而不是字符串

    我目前正在使用 PayPals API 并希望将其响应之一从名称 值对转换为数组 到目前为止我已经用过urldecode 将响应解码为以下内容 email protected email protected MOREINFO lots mo
  • 如何跟踪和检查捆绑的 Ruby gem 中的依赖关系

    Bundler 将自动安装指定 gem 的任何依赖项 但它不会在标准输出中输出哪些依赖项映射到哪些 gem 当依赖项之一安装失败时 该信息非常有用 有没有办法将 Bundler 设置得更详细并在安装时告知依赖项 我正在使用 Bundler
  • DTE.执行命令并等待

    我想使用宏来发布我的网络应用程序项目 小问题是 DTE ExecuteCommand 异步运行 我需要等待命令完成 Example DTE Windows Item Constants vsWindowKindSolutionExplore
  • T-SQL Case 语句以 newid() 作为随机源的奇怪行为

    我正在使用 SQL Server 2012 如果我执行以下操作来获取 1 3 范围内的随机数字列表 则效果很好 SELECT TOP 100 ABS CHECKSUM NEWID 3 1 value of rand FROM sys obj
  • 有没有办法将音频文件发送到语音转文本识别

    我想要 Android 语音识别系统分析音频文件 而不是来自麦克风的默认传入语音 有什么办法可以做到这一点吗 谢谢 cmusphinx sourceforge net wiki tutorialandroid 刚刚发现该链接听起来像是有人创
  • 如何使用 py2exe 减小 exe 的大小

    我使用 python 和 wxwidgets 开发了一个小程序 这是一个非常简单的程序 仅使用一个迷你框架在需要时显示一些信息 其余时间则不显示任何内容 仅在任务栏中显示一个图标 当我使用 py2exe 单文件 exe 模式 优化 构建 e
  • SQL Server 2005 如何清除查询执行计划

    各位程序员大家好 我有一个 SQL Server 2005 查询 第一次处理需要很长时间 第一次运行后 查询的运行速度要快得多 从一分钟到一秒 我知道 SQL Server 正在缓存执行计划 这个术语正确吗 我想做的就是明确这个执行计划 以
  • 异常与断言

    Java异常处理和使用异常处理有什么区别assert状况 众所周知 Assert 有两种类型 但我们什么时候应该使用assert关键词 使用断言进行代码中的内部逻辑检查 并使用正常异常来处理直接代码控制之外的错误情况 不要忘记断言可以打开和
  • 如何正确解析由空格分隔的文本文件

    下面是我的示例文本文件 这是我的架构文件 Sample File txt ColNameHeader True Format TabDelimited CharacterSet ANSI 这是我迄今为止编写的用于尝试读取上述示例文件的代码
  • python 是否允许我在运行时将动态变量传递给装饰器?

    我正在尝试在工作中集成一个非常旧的系统和一个较新的系统 我能做的最好的事情就是利用系统使用的 RSS 消防站类型提要 目标是使用此 RSS 源让其他系统在某些人做某事时执行某些操作 我的想法是在某些函数周围封装一个装饰器来检查用户 RSS