简体   繁体   中英

Finding a list of variables in python program without running the program explicitly

I need to get all the variables in a python program, but I am not allowed to run the program. I can however run it by calling it from a main program and analyze the local variables.

ast is your friend. It allows you to take advantage of the actual Python parser, but not actually execute the parsed code.

That said, this will only give you a first-order approximation - since Python allows dynamic creation of variables, static analysis can't predict 100% of all variable creation.

You can't do this. The variables in a Python program depend on the execution path. They're all instantiated dynamically. For example.

if path == 0:
   x = 1
else:
   z = 1
   w = 2

And let's say path is something read out of a file or from the user. Can you specify how many variables will be defined after this block is executed?

A more pathological case would be something like this

if path == 0:
   locals()['x'] = 1

This will create a local variable x but it's using an assignment statement so you can't even catch it using the ast module.

Please correct me if I'm wrong, but I'd say anything with an AST is likely overkill here. Isn't a variable anything that appears on the left-hand side of an assignment statement?

Edit: read the manual here and here

It would seem that "variables" are a specific instance of identifiers to which values can be bound. In the context of the Python execution model, these are known as "objects" which are bound to "names".

If a name is bound in a block, it is a local variable of that block. If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.

And here's the sweet stuff (my emphasis):

The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment , for loop header, in the second position of an except clause header or after as in a with statement. The import statement of the form from ... import * binds all names defined in the imported module, except those beginning with an underscore. This form may only be used at the module level.

So if you can cover those bases, you're set! :)

I assume that any code you analyze with this is going to be fairly rudimentary Python code; otherwise you may want to go with an AST as suggested above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM