从config中导入参数,如果不存在则先创建config

问题描述 投票:0回答:2

我有一些全局常量,它们保存在 .py 文件中,并且代码库中的许多不同位置都需要它们:

from important_parameters import ROOT_DIR, ANOTHER_DIR

许多文件都需要这种导入,我认为这比一直传递它更方便。 问题是,这些参数取决于用户,即这些是相对目录路径。也就是说,如果另一个用户运行该脚本,则必须首先创建配置文件。所以我在想这样的事情:

if not os.path.exists('important_parameters.py'):
   args = parser.parse_args()
   create_params_file(args)

参数可以在顶部指定,例如:

parser = argparse.ArgumentParser()
parser.add_argument(
    '--root_data_dir', type=str,required=True
)
parser.add_argument(
    '--another_data_dir', type=str, required=True
    )

之后,我们可以创建配置文件:

def create_params_file(args):
    with open('important_parameters.py', 'w') as file:
        file.write(f'ROOT_DIR = "{os.path.join(args.root_data_dir)}"\n')
        file.write(f'ANOTHER_DIR = "{os.path.join(args.another_data_dir)}"\n')

并在主块中使用 if 条件:

if __name__ == "__main__":
    if not os.path.exists('important_parameters.py'):
        args = parser.parse_args()
        create_params_file(args)

但是,如果文件不存在,这将不起作用,因为这样我会在顶部收到导入错误。有适合我情况的优雅解决方案吗?

python import
2个回答
0
投票

我认为最好的办法是在 if 语句之后直接在 main 函数中导入 importan_parameter

if __name__ == "__main__":
    if not os.path.exists('important_parameters.py'):
        args = parser.parse_args()
        create_params_file(args)

    from important_parameters import ROOT_DIR, ANOTHER_DIR

0
投票

如果您的导入是由用户在运行时提供的,那么它们实际上并不是全局常量。

通过导入模块,Python 将运行该模块代码并创建其命名空间,因此会出现错误,因为导入的代码尚未生成,因为 Python 正在寻求首先创建该导入的命名空间。

就解决方案而言,您有多种选择,但没有一个是真正推荐的:

选项1

声明一个全局变量,从用户输入中分配它并在不同的文件中使用:

# module.py #

ROOT_DIR = None
# arg parser gets user input...
ROOT_DIR = args.root_data_dir


# other_file.py #

import module

global ROOT_DIR

if ROOT_DIR is not None:
    print("Do something")

选项2

将变量添加到模块名称空间:

# main.py #

import module

user_input = input("Enter a value: ")

# Adding a variable to module's namespace
module.ROOT_DIR = user_input

# Now, you can use the variable in the module
module.foo_or_bar()

# module.py #

def foo_or_bar():
    if ROOT_DIR == "foo":
        print(ROOT_DIR)
    else:
        print("bar")
© www.soinside.com 2019 - 2024. All rights reserved.