如何获取脚本中使用的所有变量和方法名称

时间:2015-11-05 20:20:05

标签: python variables

这可能很奇怪,但我正在寻找一种方法来自动获取python脚本中的所有变量和方法。

例如,

prefix_users_sessions

我想要

a = 1
b = 2
c = 3
myList = range(10)

def someMethod(x): 
    something = do_something()
    return something

f = someMethod(b)

print f

这是一个示范性示例,我想为更大的脚本执行此操作。

4 个答案:

答案 0 :(得分:15)

ast module可以相当轻松地完成此操作。如果我们假设源存储在名为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。你没有要求xsomeMethod收到的论点),而且这并没有在Python 3上产生它。函数原型中的名字似乎没有创建{{1那个节点,去图。您可以从ast.Name ast.FunctionDef中每个条目的arg属性中提取list节点中的信息,但它可能仍然不全面;我怀疑其他定义相关名称可能会被遗漏,例如在具有继承的类声明中。您需要使用一些示例来确保您检查所有内容(假设您需要node.args.args等内容并希望使用Python 3)。

那就是说,如果引用它,x会很好地显示出来;如果您将其传递给x或以任何方式使用它,除了接收和丢弃它之外,它都会显示出来。

您还可以通过将测试扩展到:

来仅处理分配给,未使用的名称(以排除do_somethingdo_something
range

但是这也会降低names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Load)}) (在Py2和Py3中),因为定义本身并不会产生someMethod,只有使用它才会产生ast.Name。同样,您需要深入研究ast.Nodeast.FunctionDef等的ast.ClassDef内部,以获取不是{{1}的名称直接编辑。

答案 1 :(得分:3)

python导入了很多变量,因此您将获得一个长列表,但vars()将起作用。

a = 1
b = 2
c = 3
myList = range(10)

def someMethod(x): 
    something = 4
    return something

f = someMethod(b)

print vars()
终端

 $ python temp.py
{'a': 1, 'c': 3, 'b': 2, 'myList': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'f': 4, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'temp.py', '__package__': None, 'someMethod': <function someMethod at 0x10759b488>, '__name__': '__main__', '__doc__': None}

修改
您可以通过检查变量类型来清理它

import types
all_vars = dict(vars())
for var_name, var in all_vars.iteritems():
    if type(var) not in [types.ModuleType, types.FunctionType] and not var_name.startswith("_"):
        print var_name
终端

$ python temp.py
a
c
b
myList
f

答案 2 :(得分:2)

您可以使用globals()函数获取模块中的所有全局名称,并且由于python默认情况下有一些全局名称,例如__builtins__,您可以将它们转义:

由于globals()返回的字典包含名称和值,而内置名称的格式类似__builtins__,您可以过滤它们:

>>> print([var for var in globals().keys() if '__' not in var])
['someMethod', 'c', 'b', 'a', 'myList']

但请注意,它不会像something那样为您提供函数内的本地名称。为此,您可以看到inspect模块https://docs.python.org/3/library/inspect.html#inspect.getmembers

答案 3 :(得分:1)

您可以使用内置的dir()。假设您将文件保存为test.py.您可以执行以下操作:

>>> import test

>>> dir(test)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'b', 'c', 'f', 'myList', 'someMethod']
>>>