It can be weird but I am looking for a way to get automatically all variables and method within a python script.
For example,
a = 1
b = 2
c = 3
myList = range(10)
def someMethod(x):
something = do_something()
return something
f = someMethod(b)
print f
I want to get
a, b, c, someMethod, something, f
This is a demonstrative example, I want to do this for a much bigger script.
The ast
module can do this fairly easily. If we assume the source is stored in a variable named source
(could be read from a file):
import ast
root = ast.parse(source)
names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name)})
That loses ordering to gain uniquification and friendly display order, but you could just use a list comprehension or generator expression instead of a set comprehension if you don't need uniqueness but want ordering. The resulting list
is:
['a', 'b', 'c', 'do_something', 'f', 'myList', 'range', 'someMethod', 'something', 'x']
Unlike the other solutions posted so far, this will recurse into classes and functions to get the names used inside them, and doesn't require you to import the module or class to check, nor does it require you to implement recursive processing yourself; any syntactically valid Python code will work.
Oddly, on Python 3 (substituting a valid print
function call), you get:
['a', 'b', 'c', 'do_something', 'f', 'myList', 'print', 'range', 'someMethod', 'something']
which adds print
(as expected; it's a name now, not a keyword statement), but omits x
. You didn't ask for x
(the argument received by someMethod
), and this doesn't produce it on Python 3. Names in function prototypes appear to not create a ast.Name
node there, go figure. You can pull that info out of the ast.FunctionDef
node from the arg
attribute of each entry in the list
node.args.args
, but it's probably still not comprehensive; I suspect other definition related names might be missed, e.g. in class declarations with inheritance. You'd need to poke around with some examples to make sure you're checking everything (assuming you want stuff like x
and want to work on Python 3).
That said, x
would show up just fine if you referenced it; if you passed it to do_something
or used it in any way besides receiving and discarding it, it would show up.
You can also make an effort to only handle names assigned to, not used (to exclude do_something
, range
) by extending the test to:
names = sorted({node.id for node in ast.walk(root) if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Load)})
But that will also drop someMethod
(in both Py2 and Py3) because the definition itself doesn't produce an ast.Name
, only the use of it does. So again, you'd have to delve a little deeper into the ast.Node
internals for ast.FunctionDef
, ast.ClassDef
, etc. to get the names that aren't walk
-ed directly.
There are a lot of variables imported by python so you're going to get a long list, but vars()
will work.
a = 1
b = 2
c = 3
myList = range(10)
def someMethod(x):
something = 4
return something
f = someMethod(b)
print vars()
in terminal:
$ 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}
EDIT
You can clean it up a bit by checking for type of variables
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
in terminal:
$ python temp.py
a
c
b
myList
f
You can use globals()
function to get all the global names in your module, and since python has some global names by default like __builtins__
you can escape them :
Since globals()
return a dictionary contains the names and the values and builtin names have a format like __builtins__
you can filter them:
>>> print([var for var in globals().keys() if '__' not in var])
['someMethod', 'c', 'b', 'a', 'myList']
But note that it won't give you the local names inside the function like something
. For that aim you can see inspect
module https://docs.python.org/3/library/inspect.html#inspect.getmembers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With