You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过编程获取Jinja2命名空间中所有一级键的列表?

如何通过编程获取Jinja2命名空间中所有一级键的列表?

嘿,我之前开发Jinja2自定义扩展时也碰到过一模一样的困惑,刚好能给你指个明路!

其实你已经离答案很近了——Jinja2的Namespace对象内部是用__dict__来存储我们动态添加的属性的,只是你之前没在运行时直接访问它而已。你用dir(value)拿到的是对象的所有属性(包括内置方法和内部私有属性),但我们要的一级键其实都藏在value.__dict__里,只要过滤掉那些下划线开头的内部属性就行。

先给你修改一下你现有的InspectExtension代码,重点调整_render方法:

import pprint

from jinja2 import nodes
from jinja2.ext import Extension

class InspectExtension(Extension):

    tags = {"inspect"}

    def __init__(self, environment):
        super().__init__(environment)

    def parse(self, parser):
        lineno = parser.stream.expect("name:inspect").lineno
        expr = parser.parse_expression()
        context = nodes.DerivedContextReference()

        return nodes.Output([
            nodes.Const(expr),                            # 查看AST节点
            nodes.TemplateData('\n'),                     # 优化输出格式
            self.call_method("_render", [expr, context])  # 运行时检查
        ]).set_lineno(lineno)

    def _render(self, value, context):
        # 提取命名空间的一级键,过滤Jinja2内部的下划线开头属性
        namespace_keys = [k for k in value.__dict__ if not k.startswith('_')]
        result = {
            "class": value.__class__.__name__,
            "namespace_keys": namespace_keys,
            "context": list(context.get_all().keys())
        }
        return pprint.pformat(result, compact=False)

inspect = InspectExtension

用这个修改后的代码跑你的测试模板,就能在输出里看到"namespace_keys": ["test"]了,这就是你要的一级键列表。

再聊聊你提到的几个疑问点:

  • 关于NSRef节点:这个确实文档极少,它本质是Jinja2内部用来引用命名空间属性的节点类型(比如模板里写ns.test时底层可能会用到),但对于我们获取所有键的需求来说,完全没必要绕这个弯,运行时直接访问__dict__简单得多。
  • 关于AST层面的尝试:如果你想在模板解析阶段(parse方法里)获取命名空间的键,其实不太现实——因为命名空间的键是运行时动态添加的,解析模板的时候这些键还不存在,所以只能在运行时(也就是_render方法里)去获取。
  • 你之前想的For节点遍历:因为命名空间本身不是可迭代对象(除非你给它手动实现__iter__方法),所以直接遍历不行,但通过__dict__拿到键列表后,就可以在模板里用循环输出了。

要是你还想让命名空间本身支持直接迭代(比如模板里写{% for k in ns %}),也可以给Jinja2环境加个自定义过滤器,或者扩展Namespace类,但对于你的扩展需求来说,上面的方法已经足够解决问题了。

备注:内容来源于stack exchange,提问作者mesr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:59:37