查看另一个Python文件的变量而不导入/运行

4
我一直在尝试阅读Python文件并打印其变量。是否可以在不导入或运行它的情况下查看和打印另一个文件的变量?我已经搜索过的所有内容都只是解释如何导入或使用execfile等...(免责声明,我可能很蠢)
这是我目前为止的代码:
for vars in dir():
   print(vars)

现在,这段代码对于它所在的文件来说完全正常运行。但是当我尝试使用以下代码时:
for vars in file:
   print(vars)

(file就是path.read()的简写)

这段代码会把文件的每个字符都打印到新的一行。我不确定我的循环是否正确。我需要写一些代码来手动查找每个变量,然后将它们添加到列表中吗?


你可以从Python源文件解析器中获得一些灵感:https://dev59.com/lnRA5IYBdhLWcg3w9ivq - Vlad Frolov
1
什么是“变量”? - Azat Ibrakov
请提供您想要从中读取“变量”的模块示例和期望的输出。 - Azat Ibrakov
我指的是像 variable = "hello" 这样简单的东西。 - Kaigott
1
你可以编译它,然后反汇编它。请参阅compiledis - Peter Wood
3个回答

8
使用ast.parse来解析代码,通过迭代具有body属性(即代码块)的节点递归遍历节点,查找Assign对象并获取其targets(这些是被赋值的变量,也就是你要找的内容)并获取它们的id属性,如果它们是Name对象。将以下代码中的file.py替换为要解析的Python脚本的文件名后尝试。
import ast
import _ast

def get_variables(node):
    variables = set()
    if hasattr(node, 'body'):
        for subnode in node.body:
            variables |= get_variables(subnode)
    elif isinstance(node, _ast.Assign):
        for name in node.targets:
            if isinstance(name, _ast.Name):
                variables.add(name.id)
    return variables

print(get_variables(ast.parse(open('file.py').read())))

谢谢,它运行得很好!文档真的很令人困惑。你能再解释一下这个做了什么吗? - Kaigott
很高兴能帮上忙。是的,astcompile的文档都不是很详细。我不得不自己转储这些节点对象以了解它们的数据结构。我认为我已经在代码上面解释了我的逻辑。你有看不懂的代码部分吗?基本上,我的想法是,由于你只需要查找变量赋值,所以我只在代码块中查找Assign节点,并将赋值目标放入一个集合中作为返回值。 - blhsing
没有特别具体的内容,只是想了解 node 是做什么的。 - Kaigott

2

没有...而是有。

问题在于“变量”是常量还是真正的变量。

Python运行垃圾收集器。当您运行/导入模块时,它会创建变量。这些变量的作用域基于它们的使用方式。一旦它们不再使用,垃圾收集器将从内存中删除对象。

如果变量被分配了一个固定值(例如i = 1),那么您可以像读取文本文件一样读取该文件-因为它是文本文件。如果您想更改这些变量,则可以将其写成文本文件。您需要跟踪文本中的变量,就像任何文本匹配一样。

如果变量是作为代码的一部分生成的,则不行(例如,它生成目录中的文件列表并将其分配给一个变量)。您需要导入模块或更改模块,使其将输出导出到单独的文件(例如csv),然后您可以读取数据文件。


2

首先,你并不蠢,只是很少有人需要这样做。此外,我无法想到一种方法,可以在不移动变量到单独的json或pickle文件的情况下,在两个程序中后期加载它们使用json.load(filename)或类似的东西。但是,如果在另一个程序正在评估它时发生更改,则仅适用于该方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接