如何加载不同模块(.py)?
-
请教个问题,如何通过一个主.py文件来加载不同的模块,文件结构大概如下:
├── mud_main.py # 主入口
├── pymud.cfg # 配置文件,设置default_script": [" mud_main"]
├── triggers/
│ └── common_triggers.py # 通用trigger
├──commands/
│ └── fight.py如何写mud_main.py代码来加载其他文件夹下的模块?
步骤一:先把目录结构改成这样的
> > |-----mud_main.py # 主入口 > |-----pymud.cfg # 配置文件,设置default_script": [" mud_main"] > |-----xkx/ # 此处增加一个目录,作为package管理所有的下级模块 > |----- __init__.py # 此处增加一个空文件,文件名必须为 __init__.py 用来指示 xkx 这个目录是一个 package。下级每一个子目录都要增加一个 __init__.py 的空文件 > |----- main.py # 建议增加一个包内的最终管理文件,通用的配置都放在这里,mud_main.py仅保留入口检查功能 > |----- triggers/ > |----- __init__.py # 空文件,指示为package > |----- common_triggers.py # 通用trigger > |----- commands/ > |----- __init__.py # 空文件,指示为package > |----- fight.py # fight 模块步骤二: mud_main.py 的内容写成这样的
import os from pymud import IConfig, Session class EntryConfig(IConfig): def __init__(self, session: Session, *args, **kwargs): reload = kwargs.get("reload", False) # 处理参数里的 reload, 用于支持 #reload mud_main 就可以重新加载所有脚本 self.session = session # 脚本加载顺序 mods = list() current_dir = os.path.dirname(__file__) # 获取当前文件所在的目录 root_dir = os.path.join(current_dir, "xkx") # 当前目录下的xkx目录 dir = os.path.join(root_dir, "triggers") # 处理triggers子目录下的所有文件 if os.path.exits(dir): for file in os.listdir(dir): if file.endswith(".py") and (not file.startswith("__")): #获取目录下的所有.py文件,并排除 __init__.py mods.append(f"xkx.triggers.{file[:-3]}") dir = os.path.join(root_dir, "commands") # 处理 commands目录下的所有文件,原理同上 if os.path.exists(dir): for file in os.listdir(dir): if file.endswith(".py") and (not file.startswith("__")): #获取目录下的所有.py文件,并排除 __init__.py mods.append(f"xkx.commands.{file[:-3]}") mods.append("xkx.main") # 通用的main文件可能会调用其他模块内容,放在最后 session.load_module(mods) if reload: # 处理 reload session.reload_module(mods) self.mods = mods # 保存mods供unload使用 def __unload__(self): # 卸载时按照加载的反向顺序逐个卸载 for mod in reversed(self.mods): self.session.unload_module(mod)后续要往子目录里增加文件,直接加 xxx.py 就可以了,在子目录下的文件会被自动获取并加载。
-
可否这样优化结构?
根目录下只放pymud.cfg。子目录放不同的mud游戏的文件夹,比如xkx和thu_xyj,然后其对应目录中放一个入口的py文件,比如xkx_entry.py。
但我不明白main.py还可以放什么代码|-----pymud.cfg # 配置文件,不同的游戏设置对应的default_script
|-----xkx # 存放所有xkx所有相关的脚本
|----- __init__.py # 指示 xkx 这个目录是一个 package。
|----- xkx_entry.py # xkx脚本入口
|----- main.py # 不知道需要放哪些通用的配置?
|----- triggers/
|----- __init__.py # 空文件,指示为package
|----- common_triggers.py # 通用trigger
|----- commands/
|----- __init__.py # 空文件,指示为package
|----- fight.py # fight 模块
|-----thu_xyj # 存放所有xkx所有相关的脚本, 与xkx类似
|----- __init__.py # 指示这个目录是一个 package。
|----- thu_entry.py # thu_xyj脚本入口, 其他文件略
|-----utils # 存放通用的方法,比如中文数字转换为阿拉伯数字的方法
|----- __init__.py # 指示 这个目录是一个 package。
|----- utils.py # thu_xyj脚本入口, 其他文件略 -
最终的xkx_entry.py文件
import sys import os from pymud import IConfig, Session class EntryConfig(IConfig): def __init__(self, session: Session, *args, **kwargs): reload = kwargs.get("reload", False) # 处理参数里的reload, 用于支持 #reload self.session = session modules = list() root_dir = os.path.dirname(__file__) # 获取当前文件所在的目录 root_folder_name = os.path.basename(root_dir) # 获取当前文件所在的目录名 if os.path.exists(root_dir): for item in os.listdir(root_dir): #优先加载根目录.py文件,并排除 __init__.py if (not os.path.isdir(os.path.join(root_dir,item))) and item.endswith(".py") and (not item.startswith("__")) and (not item.endswith("entry.py")): modules.append(f"{root_folder_name}.{item[:-3]}") for item in os.listdir(root_dir): #二次循环,加载子文件夹下的.py文件,并排除 __init__.py if os.path.isdir(os.path.join(root_dir,item)) and (not item.startswith("__")): for file in os.listdir(os.path.join(root_dir,item)): if (not os.path.isdir(os.path.join(root_dir,item,file))) and file.endswith(".py") and (not file.startswith("__")): modules.append(f"{root_folder_name}.{item}.{file[:-3]}") session.load_module(modules) if reload: # 处理 reload session.reload_module(modules) self.modules = modules # 保存mods供unload使用 def __unload__(self): # 卸载时按照加载的反向顺序逐个卸载 for mod in reversed(self.modules): self.session.unload_module(mod) -
-
@shanghua 在 如何加载不同模块(.py)? 中说:
https://www.pkuxkx.net/forum/thread-50002-1-1.html
跟这帖子不一样吗?
一样的,就是这个

