我有一些全局常量,它们保存在 .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)
但是,如果文件不存在,这将不起作用,因为这样我会在顶部收到导入错误。有适合我情况的优雅解决方案吗?
我认为最好的办法是在 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
如果您的导入是由用户在运行时提供的,那么它们实际上并不是全局常量。
通过导入模块,Python 将运行该模块代码并创建其命名空间,因此会出现错误,因为导入的代码尚未生成,因为 Python 正在寻求首先创建该导入的命名空间。
就解决方案而言,您有多种选择,但没有一个是真正推荐的:
声明一个全局变量,从用户输入中分配它并在不同的文件中使用:
# 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")
将变量添加到模块名称空间:
# 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")