可能很奇怪,但我正在寻找一种自动获取python脚本中所有变量和方法的方法。
例如,
a = 1
b = 2
c = 3
myList = range(10)
def someMethod(x):
something = do_something()
return something
f = someMethod(b)
print f
我想得到
a, b, c, someMethod, something, f
这是一个演示示例,我想针对更大的脚本进行此操作。
该ast
模块可以很容易地做到这一点。如果我们假设源存储在名为source
(可以从文件读取)的变量中:
import ast
root = ast.parse(source)
names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name)})
这样就失去了获得唯一性和友好的显示顺序的顺序,但是如果您不需要唯一性但想要排序,则可以只使用列表推导或生成器表达式来代替集合推导。结果list
是:
['a', 'b', 'c', 'do_something', 'f', 'myList', 'range', 'someMethod', 'something', 'x']
与到目前为止发布的其他解决方案不同,这将递归到类和函数中以在其中使用名称,并且不需要您导入要检查的模块或类,也不需要您自己实现递归处理;任何语法上有效的Python代码都可以使用。
奇怪的是,在Python 3上(替换为有效的print
函数调用),您得到:
['a', 'b', 'c', 'do_something', 'f', 'myList', 'print', 'range', 'someMethod', 'something']
它添加了print
(按预期;现在是名称,而不是关键字语句),但是省略了x
。您没有要求x
(接收到的参数someMethod
),并且在Python 3上也没有产生它。函数原型中的名称似乎并未在ast.Name
那里创建节点,请参见图。您可以ast.FunctionDef
从中的arg
每个条目的属性将信息从节点中拉出list
node.args.args
,但是它可能仍然不全面。我怀疑可能会遗漏其他与定义相关的名称,例如在带有继承的类声明中。您需要仔细研究一些示例,以确保您检查了所有内容(假设您想要类似的东西x
并且想要在Python 3上工作)。
就是说,x
如果您引用它,它将很好地显示出来;如果您将其传递给do_something
或使用了它(除了接收和丢弃它之外),它还会显示出来。
您也可以作出努力,分配给,不使用(排除只手柄名称do_something
,range
由测试延伸至):
names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Load)})
但这也会下降someMethod
(在Py2和Py3中),因为定义本身不会产生ast.Name
,只有使用它会产生。如此反复,你就必须钻研得更深一些,到ast.Node
内部的ast.FunctionDef
,ast.ClassDef
等拿到未的名字walk
直接-ed。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句