标识作为调用方范围内的字符串列表的变量
Identify variables that are lists of strings in the caller scope
我想识别用户在他们的交互式 shell 中定义的所有字符串列表。
def lists_of_strings():
d = dict(globals(), **locals())
d = {k:v for (k, v) in d.items() if not k.startswith("_") and k != 'In'}
res = {}
for k, v in d.items():
if isinstance(v, list):
if all(map(lambda x: isinstance(x, str), v)):
res[k] = v
return res
当我在当前 shell 中定义此函数时,它起作用了:
>>> lists_of_strings()
{}
>>> mylist = ["a", "b"]
>>> lists_of_strings()
{"mylist": ["a", "b"]}
现在,如果我将此函数移动到模块 mymodule
中并导入它:
>>> from mymodule import lists_of_strings
>>> lists_of_strings()
{}
>>> mylist = ["a", "b"]
>>> lists_of_strings()
{}
函数总是returns一个空字典。为什么会这样,更重要的是,我可以修复它吗?
一些上下文:我正在尝试在我的模块中编写一个帮助程序来识别用户在当前 jupyter notebook 中定义的合适变量。我的目标是询问用户是否想将这些变量用作某些预定义函数的参数。
Python 的 globals
内置 returns 包含 当前模块 的全局变量的字典。这是一个非常好的特性,因为 "global" 变量不是进程范围的,而且是模块(因此也是文件)范围的——允许每个模块作为一个命名空间工作。这简化了很多工作,以避免在大型系统中发生名称冲突(如果使用第三方组件,则会加倍如此)。
但是,是的,有一种方法可以访问另一个 运行ning 上下文的全局变量。在 frame
对象的上下文中,所有 Python 代码都是 运行 - 它保留对当前使用的实际字节码、局部变量和全局变量的引用。框架对象的 f_globals 属性实际上是 globals
内置函数返回的同一个字典。
因此,您所要做的就是获取对函数调用发生的帧对象的引用 - 这可以通过获取当前帧的 .f_back
属性来完成。
这意味着如果您将函数更改为:
,您的函数将跨模块工作(并在导入时)
import sys
def lists_of_strings():
caller_frame = sys._getframe().f_back
d = dict(caller_frame.f_globals, **caller_frame.f_locals)
d = {k:v for (k, v) in d.items() if not k.startswith("_") and k != 'In'}
res = {}
for k, v in d.items():
if isinstance(v, list):
if all(map(lambda x: isinstance(x, str), v)):
res[k] = v
return res
也就是说,重要的是要注意并非所有代码都需要使用框架。如果你只想知道已知模块中的 global 变量,你可以只使用该模块的 __dict__
属性:
import math
print (math.__dict__)
我想识别用户在他们的交互式 shell 中定义的所有字符串列表。
def lists_of_strings():
d = dict(globals(), **locals())
d = {k:v for (k, v) in d.items() if not k.startswith("_") and k != 'In'}
res = {}
for k, v in d.items():
if isinstance(v, list):
if all(map(lambda x: isinstance(x, str), v)):
res[k] = v
return res
当我在当前 shell 中定义此函数时,它起作用了:
>>> lists_of_strings()
{}
>>> mylist = ["a", "b"]
>>> lists_of_strings()
{"mylist": ["a", "b"]}
现在,如果我将此函数移动到模块 mymodule
中并导入它:
>>> from mymodule import lists_of_strings
>>> lists_of_strings()
{}
>>> mylist = ["a", "b"]
>>> lists_of_strings()
{}
函数总是returns一个空字典。为什么会这样,更重要的是,我可以修复它吗?
一些上下文:我正在尝试在我的模块中编写一个帮助程序来识别用户在当前 jupyter notebook 中定义的合适变量。我的目标是询问用户是否想将这些变量用作某些预定义函数的参数。
Python 的 globals
内置 returns 包含 当前模块 的全局变量的字典。这是一个非常好的特性,因为 "global" 变量不是进程范围的,而且是模块(因此也是文件)范围的——允许每个模块作为一个命名空间工作。这简化了很多工作,以避免在大型系统中发生名称冲突(如果使用第三方组件,则会加倍如此)。
但是,是的,有一种方法可以访问另一个 运行ning 上下文的全局变量。在 frame
对象的上下文中,所有 Python 代码都是 运行 - 它保留对当前使用的实际字节码、局部变量和全局变量的引用。框架对象的 f_globals 属性实际上是 globals
内置函数返回的同一个字典。
因此,您所要做的就是获取对函数调用发生的帧对象的引用 - 这可以通过获取当前帧的 .f_back
属性来完成。
这意味着如果您将函数更改为:
,您的函数将跨模块工作(并在导入时)import sys
def lists_of_strings():
caller_frame = sys._getframe().f_back
d = dict(caller_frame.f_globals, **caller_frame.f_locals)
d = {k:v for (k, v) in d.items() if not k.startswith("_") and k != 'In'}
res = {}
for k, v in d.items():
if isinstance(v, list):
if all(map(lambda x: isinstance(x, str), v)):
res[k] = v
return res
也就是说,重要的是要注意并非所有代码都需要使用框架。如果你只想知道已知模块中的 global 变量,你可以只使用该模块的 __dict__
属性:
import math
print (math.__dict__)