python Flask如何将动态参数传递给装饰器

2024-02-16

我正在使用 python Flask 框架。我写了一个装饰器,它需要一个参数,并且这个参数将是动态的。

我的装饰器如下所示,将获得一个密钥,并使用该密钥从 Redis 获取数据。

def redis_hash_shop_style(key):
    def fn_wrapper(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            data = redis_hash(key)
            return data
        return decorated_function
return fn_wrapper

我有一个使用这个装饰器的类,代码如下

class ShopAreaAndStyleListAPI(Resource):
    @redis_hash_shop_style(key='shop_{}_style'.format(g.city.id))
    def get(self):
        # if not found from redis, query from mysql
        pass

如您所见,我的装饰器需要一个名为的参数key,我这样传递密钥

@redis_hash_shop_style(key='shop_{}_style'.format(g.city.id)) g.city.id将获取城市的 id,如果一切正常,密钥将是这样的

shop_100_style

但我收到错误:

class ShopAreaAndStyleListAPI(Resource):
File "xx.py", line 659, in ShopAreaAndStyleListAPI

@redis_hash_shop_style(key='shop_{}_style'.format(g.city.id))

File "/Users/xx/.virtualenvs/yy/lib/python2.7/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/xx/.virtualenvs/yy/lib/python2.7/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/Users/xx/.virtualenvs/yy/lib/python2.7/site-packages/flask/globals.py", line 44, in _lookup_app_object
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that 
needed to interface with the current application object in a way.  
To solve this set up an application context with app.app_context().  
See the documentation for more information.

我很困惑,在烧瓶中,如何将动态参数传递给装饰器?

Thanks.


如果我们检查文档烧瓶应用全球 http://flask.pocoo.org/docs/0.12/api/#application-globals, flask.g, 它说:

要将仅对一个请求有效的数据从一个函数共享到另一个函数,全局变量还不够好,因为它会在线程环境中中断。 Flask 为您提供了特殊物体这确保了它是仅对活动请求有效这将为每个请求返回不同的值。

这是通过使用线程本地代理来实现的(在flask/globals.py https://github.com/pallets/flask/blob/master/flask/globals.py#L61):

g = LocalProxy(partial(_lookup_app_object, 'g'))

我们应该记住的另一件事是,Python 在“编译”阶段执行装饰器的第一遍,在任何请求之外,或者flask应用。这意味着key参数被赋值为'shop_{}_style'.format(g.city.id)当您的应用程序启动时(当您的类正在被解析/装饰时),在flask请求上下文。

但我们可以很容易地延迟访问flask.g通过使用惰性代理,该代理仅在使用时通过回调函数获取值。让我们使用已经捆绑的那个flask, the werkzeug.local.LocalProxy http://werkzeug.pocoo.org/docs/0.12/local/#werkzeug.local.LocalProxy:

from werkzeug.local import LocalProxy

class ShopAreaAndStyleListAPI(Resource):
    @redis_hash_shop_style(key=LocalProxy(lambda: 'shop_{}_style'.format(g.city.id)))
    def get(self):
        # if not found from redis, query from mysql
        pass

一般来说(对于非flask or non-werkzeug应用程序),我们可以使用类似的LazyProxy来自ProxyTypes https://pypi.python.org/pypi/ProxyTypes/0.9包裹。

与此无关,您还需要修复您的redis_hash_shop_style装饰器不仅可以从中获取redis,但如果过时(或不存在),也可以通过调用包装的f()在适当的时候。

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

python Flask如何将动态参数传递给装饰器 的相关文章

随机推荐

  • 如何导入子目录中的模块,从而导入同一子目录中的另一个模块?

    在我导入的模块中 我尝试导入位于同一目录中的另一个模块 我的文件看起来像这样 project main py app foo py bar py main py import app foo as Foo foo py import bar
  • UnityWebRequest 在 iOS 中不工作

    给出的例子https docs unity3d com Manual UnityWebRequest html https docs unity3d com Manual UnityWebRequest html正如预期的那样 可以在 Wi
  • 为什么我们在使用Ajax控件时总是需要脚本管理器?

    为什么我们在使用Ajax控件时总是需要脚本管理器 脚本管理器控件是将脚本发送到客户端的控件 该控件是所有 AJAX 相关功能的核心 它管理启用 Ajax 的页面中的所有控件 它还确保部分页面更新按预期发生 http msdn microso
  • 如何从任何 Docker 存储库中提取单个映像?

    docker 存储库包含多个镜像 是否可以从存储库中提取特定图像 当我使用时 docker pull ubuntu 它会下载大约 8 10 个不同版本的 ubuntu 如果有标记的特定图像 您可以使用 tag 或 t 运算符来提取您要查找的
  • Android 加速度计过滤?

    我看到了许多关于过滤加速度计值以抵消重力 高通滤波器 的示例 但其中大多数都是一阶一阶 据说很简单 但是滞后 而且不是最好的 尽管我对滤波器或 DSP 一无所知 这里有人说有更好的解决方案用于DSP来感知运动 遗憾的是 我什至无法想象它会是
  • 无法将 JSON 对象插入 Firebase 实时数据库

    我正在尝试将用户数据存储在我的 Firebase 数据库中 这是我处理 onClick 并将数据发送到数据库的代码 public void onClickStore final View view String name binding g
  • 停止观察reactjs中的文件夹变化

    我正在开发一个反应项目 用户可以在其中上传文件 我面临的问题是当我将文件上传到服务器并将该文件保存到位于公共文件夹中的名为 uploads 的文件夹中时 然后当此过程完成页面刷新 这是因为应用程序正在监视任何更改并刷新页面 我知道我可以通过
  • 尽管安装并加载了 reshape2,但仍找不到功能“cast”

    跟随哈德利 威克姆 Hadley Wickham 探索数据和模型的实用工具 http had co nz thesis 2 4 节中的示例 铸造熔融数据我越来越Error could not find function cast 我已经安装
  • 一键运行 Javascript 2 个函数

    我使用从网上下载的 HTML 和 JS 代码来录制音频 但有一个问题 因为页面加载到屏幕上后立即出现允许麦克风的消息 正是因为window onload function init 在源代码record js中 但我想在单击按钮后显示消息
  • 在控制台应用程序中捕获 ctrl+c 事件(多线程)

    我有一个控制台应用程序的主线程 它以这种方式运行很少的外部进程 private static MyExternalProcess p1 private static MyExternalProcess p2 private static M
  • 304 未修改问题

    抱歉 标题可能有误 我正在编写一些代码来处理 If Modified Since 和 If None Match 请求作为缓存的一部分 除了 PHP 在标头后面返回一些内容 空行 之外 一切都很完美 页面内容应该为空 我正在使用的代码是
  • 是否可以将别名模板标记为好友?

    想象一下我们有这样的代码 template
  • 在字符串文字中展开宏

    我想做的是 define一个宏 define a 2 然后在字符串文字中使用它 string a 我希望该字符串不被解释为字符串 而是获取值a 即2 我没有成功 有人可以帮忙吗 define STRINGIFY2 X X define ST
  • 参数作用域与局部变量作用域?

    我正在读我的 AP cs 书 它谈到了三种类型的变量 实例变量 局部变量 参数 实例变量在整个类中都是可见的等等 参数只能在方法内使用 局部变量也是如此 因此 我的问题是 如果参数和局部变量包含相同的范围 为什么他们会将参数和局部变量分类为
  • MySql 适合大型数据库吗? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我在一家公司工作 我们总是访问外部网站以获取信息 该网站是由一家过时的软件开发公司开发的 该公司甚至没有网站 他们在我所在的州几乎拥有垄断地
  • 如果 Blob URL 是不可变的,Media Source Extension API 如何使用它们来流式传输视频?

    让我们从一个例子开始 您访问 youtube com 该网站在某些设备上使用带有 HTML5 的媒体源扩展 MSE MSE 使用 blob URL 注入 标记 它看起来像这样 blob https www youtube com blahb
  • 了解 xargs 中的递归 grep

    以下两个命令之间有什么实际区别 命令A find type f print0 xargs 0 grep r masi 命令B find type f print0 xargs 0 grep masi 简而言之 命令 A 的实际好处是什么 N
  • 使用Python将文件加载到内存中

    我尝试使用以下命令将文件加载到内存中 import mmap with open path fileinput example txt rb as f fileinput mmap mmap f fileno 0 prot mmap PRO
  • Python Pandas 用户警告:由于非串联轴未对齐而进行排序

    我正在做一些代码练习并在执行此操作时应用数据帧合并 收到用户警告 usr lib64 python2 7 site packages pandas core frame py 6201 FutureWarning 由于非串联轴未对齐而进行排
  • python Flask如何将动态参数传递给装饰器

    我正在使用 python Flask 框架 我写了一个装饰器 它需要一个参数 并且这个参数将是动态的 我的装饰器如下所示 将获得一个密钥 并使用该密钥从 Redis 获取数据 def redis hash shop style key de