@@ -31,8 +31,80 @@ def ensure_all_dirs_exist(self):
3131 self .CACHE_PATH .mkdir (exist_ok = True )
3232
3333
34- # 全局变量,在CLI启动时被赋值
35- paths : PathManager = None
34+ class PathManagerProxy :
35+ """
36+ 路径代理类,会在首次操作时把自己替换掉。
37+ """
38+
39+ def __init__ (self ):
40+ """
41+ 初始化代理对象,存储初始化 PathManager 所需的 work_path。
42+ """
43+ object .__setattr__ (self , '_initialized' , False ) # 标记是否已初始化真实对象
44+
45+ def _initialize_and_transform (self ):
46+ """
47+ 这个函数负责初始化真正的 PathManager 实例,并使代理对象“替换掉自己”。
48+ 它通过改变自身的 __class__ 和更新 __dict__ 来实现。
49+ """
50+ if object .__getattribute__ (self , '_initialized' ):
51+ return # 已经初始化过了,直接返回
52+
53+ work_path = os .getcwd ()
54+
55+ print (f"由于Path在未被正常初始化的时候调用,临时初始化,工作目录: { work_path } " )
56+
57+ init_paths (work_path )
58+ real_instance = paths
59+
60+ self .__dict__ .update (real_instance .__dict__ )
61+
62+ self .__class__ = PathManager
63+
64+ object .__setattr__ (self , '_initialized' , True )
65+
66+ def __getattr__ (self , name ):
67+ """
68+ 当访问代理对象上不存在的属性时(包括方法),此方法会被调用。
69+ 它会触发真实 PathManager 对象的初始化。
70+ """
71+ # 如果当前对象尚未初始化为 PathManager,则进行初始化和转换
72+ if not object .__getattribute__ (self , '_initialized' ):
73+ self ._initialize_and_transform ()
74+
75+ # 此时,self 已经变成了 PathManager 实例,其属性已在 __dict__ 或 PathManager 的方法中
76+ # 再次尝试从自身获取属性,这次会成功(如果 PathManager 有该属性/方法)
77+ return object .__getattribute__ (self , name )
78+
79+ def __setattr__ (self , name , value ):
80+ """
81+ 当设置代理对象的属性时,此方法会被调用。
82+ 它也会触发真实 PathManager 对象的初始化。
83+ """
84+ # 如果正在设置代理自身内部的延迟参数或初始化标记,直接通过基类设置,避免递归
85+ if name in ['_initialized' ]:
86+ object .__setattr__ (self , name , value )
87+ else :
88+ # 否则,表示用户正在操作一个业务属性,触发初始化
89+ if not object .__getattribute__ (self , '_initialized' ):
90+ self ._initialize_and_transform ()
91+ # 初始化完成后,通过基类设置属性,因为现在 self 已经是 PathManager
92+ object .__setattr__ (self , name , value )
93+
94+ def __delattr__ (self , name ):
95+ """
96+ 当删除代理对象的属性时,此方法会被调用。
97+ 它也会触发真实 PathManager 对象的初始化。
98+ """
99+ if name in ['_initialized' ]:
100+ object .__delattr__ (self , name )
101+ else :
102+ if not object .__getattribute__ (self , '_initialized' ):
103+ self ._initialize_and_transform ()
104+ object .__delattr__ (self , name )
105+
106+
107+ paths : PathManager = PathManagerProxy ()
36108
37109
38110def init_paths (work_path_str : str ):
@@ -42,8 +114,10 @@ def init_paths(work_path_str: str):
42114 work_path_str: 工作目录
43115 """
44116 global paths
45- paths = PathManager (Path (work_path_str ))
117+ if isinstance (paths , PathManagerProxy ):
118+ paths = PathManager (Path (work_path_str ))
46119
47120
48- if os .path .isdir (os .path .join (os .getcwd (), "murainbot" )):
121+ # 如果是 MRB2 开发环境,自动初始化
122+ if os .path .isdir (os .path .join (os .getcwd (), "murainbot" )) and os .path .isdir (os .path .join (os .getcwd (), "plugins" )):
49123 init_paths (os .getcwd ())
0 commit comments