gpt4 book ai didi

python - 检查 Python 函数是否引用了任何超出范围的内容

转载 作者:行者123 更新时间:2023-12-05 06:48:14 25 4
gpt4 key购买 nike

我正在探索用 Python 可以做什么,最近遇到了这个问题:运行一个函数后,是否可以通过编程方式确定它是否引用了任何超出范围的内容?例如:

import module1

y = 1

def foo1(x):
return y + x # yes - it has referenced 'y' which is out of foo1 scope

def foo2(x):
return module1.function1(x) # yes - it has referenced 'module1' which is out of foo2 scope

def foo3(x):
return x*x # no - it has only referenced 'x' which is an input to foo3, so the code executed within the scope of foo3

是否有一些反射(reflection)/分析工具?也许这可以通过“跟踪”模块以某种方式实现?

最佳答案

您可以使用 inspect.getclosurevars :

Get the mapping of external name references in a Python function ormethod func to their current values. A named tupleClosureVars(nonlocals, globals, builtins, unbound) is returned.nonlocals maps referenced names to lexical closure variables, globalsto the function’s module globals and builtins to the builtins visiblefrom the function body. unbound is the set of names referenced in thefunction that could not be resolved at all given the current moduleglobals and builtins.

让我们看看它为您的示例返回了什么:

案例 1:

def foo1(x):
return y + x # yes - it has referenced 'y' which is out of foo1 scope

inspect.getclosurevars(foo1)
# ClosureVars(nonlocals={}, globals={'y': 1}, builtins={}, unbound=set())

在这里它检测到您正在全局范围内使用变量。

案例 2:

import colorsys
def foo2(x):
return colorsys.rgb_to_hsv(*x) # yes - it has referenced 'colorsys' which is out of foo2 scope

inspect.getclosurevars(foo2)
# ClosureVars(nonlocals={}, globals={'colorsys': <module 'colorsys' from '...\\lib\\colorsys.py'>}, builtins={}, unbound={'rgb_to_hsv'})

在这里它检测到您正在使用模块的功能。

案例三:

def foo3(x):
return x*x # no - it has only referenced 'x' which is an input to foo3, so the code executed within the scope of foo3

inspect.getclosurevars(foo3)
# ClosureVars(nonlocals={}, globals={}, builtins={}, unbound=set())

在这里我们看到“没有异常”。

因此,我们可以将此过程包装在一个函数中,该函数会查看是否有任何字段(内置字段除外;即foo 可以使用abs 没问题)是非空的:

import inspect

def references_sth_out_of_scope(fun):
closure_vars = inspect.getclosurevars(fun)
referenced = any(getattr(closure_vars, field) for field in closure_vars._fields if field != "builtins")
return referenced

用法:

>>> references_sth_out_of_scope(foo1)
True

>>> references_sth_out_of_scope(foo2)
True

>>> references_sth_out_of_scope(foo3)
False

>>> references_sth_out_of_scope(references_sth_out_of_scope) # :)
True

关于python - 检查 Python 函数是否引用了任何超出范围的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66866092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com