import sys
import os
from os import path as osp
def add_path(path):
if path not in sys.path:
sys.path.insert(0, path)
try:
os.environ["PYTHONPATH"] = path + ":" + os.environ["PYTHONPATH"]
except KeyError:
os.environ["PYTHONPATH"] = path
this_dir = osp.dirname(__file__) # 获取当前路径
# Add lib to PYTHONPATH
lib_path = osp.join(this_dir, '..', 'lib') # 当前路径改为 这一级的路径/../lib
add_path(lib_path)
在主文件里的第一行导入该包,主文件的相对路径变为了:这一级的路径/../lib
import _init_paths
sys.path 和 eval 函数的工作原理
什么是 sys.path?
sys.path 是一个列表,包含了 Python 查找模块时会搜索的目录路径。当你导入一个模块时,Python 会按照 sys.path 中列出的顺序逐个目录进行搜索,直到找到该模块。
你可以通过 import sys 并打印 sys.path 来查看这个列表:
import sys
print(sys.path)
通常情况下,sys.path 会包含以下几类目录:
- 当前脚本所在的目录。
PYTHONPATH环境变量中列出的目录。- Python 标准库和第三方库的安装目录。
eval 函数
eval 是一个内置函数,用于执行一个字符串形式的表达式,并返回结果。在这个特定情况下,eval 被用来动态解析和调用一个类名。
动态实例化类
当代码 train_set = eval(cfg.DATASET.DATASET)("train", cfg) 执行时,发生了以下过程:
-
获取配置项:从
cfg对象中读取DATASET.DATASET,得到字符串"IMBALANCEDCIFAR10"。 -
使用
eval函数:eval(cfg.DATASET.DATASET)等价于eval("IMBALANCEDCIFAR10"),这会将字符串"IMBALANCEDCIFAR10"解析为一个类对象。 -
查找类:Python 会在当前的命名空间中查找
IMBALANCEDCIFAR10类。由于在main/_init_paths.py中已经将lib目录添加到了sys.path中,Python 知道去lib目录下查找模块。
_init_paths.py
import sys
import os
from os import path as osp
def add_path(path):
if path not in sys.path:
sys.path.insert(0, path)
try:
os.environ["PYTHONPATH"] = path + ":" + os.environ["PYTHONPATH"]
except KeyError:
os.environ["PYTHONPATH"] = path
this_dir = osp.dirname(__file__)
# Add lib to PYTHONPATH
lib_path = osp.join(this_dir, '..', 'lib')
add_path(lib_path)
这段代码将 lib 文件夹添加到 sys.path。因此,当 eval("IMBALANCEDCIFAR10") 执行时,Python 能够在 lib.dataset.imbalance_cifar 模块中找到 IMBALANCEDCIFAR10 类。
详细过程
- 添加路径:
_init_paths.py将lib文件夹添加到sys.path。 - 导入模块:当执行
train_set = eval(cfg.DATASET.DATASET)("train", cfg)时,eval将"IMBALANCEDCIFAR10"解析为类名。 - 查找类:Python 在
sys.path中的各个目录查找IMBALANCEDCIFAR10类,由于lib已经在sys.path中,所以 Python 能够找到lib/dataset/imbalance_cifar.py文件,并从中导入IMBALANCEDCIFAR10类。

7958

被折叠的 条评论
为什么被折叠?



