Listing variables from external script python with

2019-08-21 01:47发布

问题:

I'm writing a python script that gets parameters from a json file, opens a template script specified by one of the parameters (from a set of options), and generates a new python script replacing some of the template script with the parameters given in the json.

I'm currently trying to list all variables from the template as follows:

list = [item for item in dir(imported_script) if not item.startswith("__")]

So I can use the list to iterate over the variables and write them in the new script.

Problem: this result list also contains the imported modules from the mentioned imported template script. I've also tried with imported_script.__dict__ and vars(imported_script) but these solutions yield to the same. There is also the option of using help(imported_script) which returns the metadata of the script, but until now I haven't found a correct way to get what would be the equivalent to help(imported_script).DATA.

Question: Is there a more efficient way of listing the imported script variables so I get specifically the user declared variables?

More context: I'm using Airflow to generate workflows. Airflow reads a python script that specifies how the workflow (known as DAG in airflow) should be constructed. The script should be in a specific folder so airflow can make the workflow. The specifications of how the workflow should be constructed are given in a json file and vary every time the user wants to generate a workflow, so I must read this json file and then write a new script reusing the code from the template (at least that's the way I've been told to do it). There are several scripts from which I could take the code to reuse and in the future there could be even more (It's dynamic). The script to be chosen depends on one of the parameters in the json.

回答1:

It's kind of unclear what you're trying to do, but from this description you give, this problem might be more easily solved using templates than by generating code entirely from scratch in Python. You might be able to get away with plain old python format strings, or if you need more features jinja2 might be useful.

my_script.py.template

import something

{param1}_variable = 1
def {param2}_function():
    something.{something_func}

version_1.json

{
    'param1': 'foo',
    'param2': 'bar',
    'something_func': 'neato_function'
}

Then you generate the output with something like:

template = open('my_script.py.template').read()
with open('my_script_version_1.py', 'w') as f:
    f.write(template.format(**json.load(open('version_1.json'))))

All that being said...are you super sure that you want to do this? Unless there's a specific reason you need to generate a file containing the code, it might be better to use more standard methods (like using regular Python imports)


To actually answer your question: you could try to use the type function on the elements of vars(), but this seems really fragile. Modules will have type <class 'module'>. But then you also have to figure out how to filter out functions, classes, etc.