首页 > 解决方案 > 从动态文件名导入 Python

问题描述

我处于以下情况:我有一个 python 脚本main.py,它根据配置文件运行一些操作。配置文件本身就是一个 python 脚本/类。我希望能够从命令行传递不同的配置文件作为参数并将其导入主脚本。

在python中甚至可以动态加载类吗?如果是这样,我该如何完成这项任务?

请参阅以下最小示例以进行说明。

这是我的脚本main.py

import argparse

def get_arguments():
    parser = argparse.ArgumentParser(description="foo")
    parser.add_argument("--configfile", required=True)
    return parser.parse_args()

def main():
    args = get_arguments()

    from args.configfile import MyConfig # <-- how is that possible?

    if MyConfig.SETTING1:
        do_something()

if __name__ == '__main__':
    main()

这是一个例子config.py

class MyConfig(BaseConfig):
    SETTING1 = True
    SETTING2 = 1 

这是另一个例子config-special.py

class MyConfig(BaseConfig):
    SETTING1 = False
    SETTING2 = 42 

我这样称呼它:

$ python3 main.py --configfile config.py
$ python3 main.py --configfile config-special.py

标签: pythonpython-3.x

解决方案


用于import_module动态导入模块,详细解释见代码。

仍然使用你的下一个命令来调用它们。

$ python3 main.py --configfile config.py
$ python3 main.py --configfile config-special.py

主文件

import argparse
# import sys
from importlib import import_module

def get_arguments():
    parser = argparse.ArgumentParser(description="foo")
    parser.add_argument("--configfile", required=True)
    return parser.parse_args()

def main():
    args = get_arguments()
    module_name = args.configfile[:-3] # here, the result is the file name, e.g. config or config-special

    # Not use __import__, use import_module instead according to @bruno desthuilliers's suggestion
    # __import__(module_name) # here, dynamic load the config module
    # MyConfig = sys.modules[module_name].MyConfig # here, get the MyConfig class
    MyConfig = import_module(module_name).MyConfig

    # from args.configfile import MyConfig # <-- how is that possible?

    if MyConfig.SETTING1:
        #do_something()
        print("do_something")

if __name__ == '__main__':
    main()

推荐阅读