python 文字是否保存在函数体内?

Are python literals saved inside function bodies?

我有一个函数需要在一个相当紧凑的循环内执行,因此它对性能很敏感。它是一种过滤功能,旨在节省更昂贵的工作。大多数功能只是针对静态列表的检查。

所以(去掉一些不相关的细节)我可以在这里做两件不同的事情:

 def my_filter(arg):
    SAFE_VALS = {
        'a',
        'b',
        'f',
        'i',
        'm'
    }
   # the real list is much larger, but 
   # it is a static set like the above...

    return arg in SAFE_VALS

 # make this a module level constant
 SAFE_VALS = {
        'a',
        'b',
        'f',
        'i',
        'm'
    }

 def my_filter(arg):
    return arg in SAFE_VALS

我知道 Python 必须查找更高一级的作用域才能找到模块级别的版本——但我不知道 my_filter 的编译版本是否有效地重新创建了这个每次函数为 运行 或文字被“烘焙”到函数 def 时设置。如果每次调用都分配一个新集合,感觉我最好使用模块级版本——如果不是,我不会通过将文字提升到函数范围之外来获得任何好处。

现在分析数据非常嘈杂,我看不出有什么明显区别。但是,如果该集合包含更多的长字符串,我会吗?或者这些形式之间现在有显着差异吗?

作为语言语义的问题,{'a', 'b', 'f', 'i', 'm'} 的意思是“用这些内容创建一个 new 集合”。语言语义允许为不可变类型重用现有对象,但集合是可变的。

作为实现细节,CPython 目前优化了形式为 x in {stuff} 的表达式,其中右侧是仅包含常量的集合表达式。在这种情况下,Python 将预先计算一个冻结集并将其保存在代码对象的 co_consts 中。将集合保存到变量会阻止优化。

为了保证不重新计算集合,独立于实现细节,您应该自己预先计算集合并将SAFE_VALS保存为全局变量。