Python脚本顶部用函数初始化常量报未定义错误,求更优实现方案
问题核心原因
Python是解释执行的,代码从上到下逐行运行,你在build_master_config_dictionary()函数定义前就调用它,自然会报未定义错误。另外注意你当前的函数没有写return语句,就算把赋值移到底部,得到的也会是None,需要先补上return。
可选优化方案
方案1:惰性加载常量(最贴合你要把常量放顶部的需求)
通过一个简单的惰性加载包装类,声明常量时仅绑定加载函数,不会立刻执行,第一次实际使用常量时才会触发加载逻辑,既保留了顶部常量的可读性,也不存在执行顺序问题:
import json from pathlib import Path from glob import glob # 惰性加载工具类,仅需定义一次即可供所有同类常量复用 class LazyLoader: def __init__(self, load_func): self._load_func = load_func self._value = None def __call__(self): if self._value is None: self._value = self._load_func() return self._value # 所有常量统一放顶部 JSON_CONFIG_DIR = "data\JSON\Configs" # 仅绑定加载函数,不立刻执行 MASTER_CONFIG_SITE_DICT = LazyLoader(build_master_config_dictionary) # 函数定义放常量之后 def build_master_config_dictionary(): master_json_file_dict = {} for relative_fp in glob(f"{JSON_CONFIG_DIR}\*.json"): try: with open(relative_fp) as f: filename = Path(relative_fp).stem master_json_file_dict[filename] = json.load(f) except Exception as e: print(f'build_master_config_dictionary: unable to load in json file - {relative_fp}') return master_json_file_dict
使用时调用MASTER_CONFIG_SITE_DICT()即可获取配置字典,只会在第一次调用时加载一次,后续调用直接返回缓存结果。如果要实现和普通变量完全一致的调用方式,可以把LazyLoader放在模块级别用描述符实现,使用逻辑完全不变。
方案2:模块级Getter函数(更适合多脚本调用场景)
把配置封装成获取函数,对外暴露统一的调用入口,避免全局变量直接暴露,还能天然实现单例加载,适合项目内其他脚本调用的场景:
import json from pathlib import Path from glob import glob # 所有静态常量统一放顶部 JSON_CONFIG_DIR = "data\JSON\Configs" # 内部缓存变量,不对外暴露 _MASTER_CONFIG_CACHE = None # 对外暴露的获取接口 def get_master_config(): global _MASTER_CONFIG_CACHE if _MASTER_CONFIG_CACHE is None: _MASTER_CONFIG_CACHE = _build_master_config_dictionary() return _MASTER_CONFIG_CACHE # 内部加载函数,用下划线开头标记为模块私有 def _build_master_config_dictionary(): master_json_file_dict = {} for relative_fp in glob(f"{JSON_CONFIG_DIR}\*.json"): try: with open(relative_fp) as f: filename = Path(relative_fp).stem master_json_file_dict[filename] = json.load(f) except Exception as e: print(f'build_master_config_dictionary: unable to load in json file - {relative_fp}') return master_json_file_dict
其他脚本调用时直接导入get_master_config函数调用即可,不需要关心内部加载逻辑。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

