首页 > 编程语言 >python调用项目外py文件问题及解决方案

python调用项目外py文件问题及解决方案

时间:2023-01-04 12:01:49浏览次数:77  
标签:__ python 解决方案 self py sys import path

问题来源:   为了支持模型的切换功能,拟通过调用不同模型路径下的predict.py方法来实现。这就涉及到调用外部py文件。调用外部py文件,有多种方式:

方法一:sys.path

1 import sys
2 sys.path.insert(0, modelPath) # 设置该目录拥有最高优先级
3 import predict

  问题1:不符合python的PEP-8规范(即import语句应放在代码的最前面),可参考这篇给出的解决方案

  问题2:使用sys.path时,在程序运行过程中始终有效,每次使用后应注意及时删除已添加的路径

 1 # 定义
 2 class add_path:
 3     def __init__(self, path):
 4         self.path = path
 5 
 6     def __enter__(self):
 7         sys.path.insert(0, self.path)
 8 
 9     def __exit__(self, exc_type, exc_value, traceback):
10         try:
11             sys.path.remove(self.path)
12         except ValueError:
13             pass
  
1 # 使用
2 with add_path(modelPath):
3     import predict
4     XXXX

 

  问题2-1:但进一步在真实的使用中发现,尽管我们在sys.path中删除了对应的路径,下次import predict时仍然会延续上一次的引入结果。这是因为sys.modules缓存路径(python在import module前,先会去sys.modules看看曾经有没有导入过这个模块)如果已经导入过就不会再从sys.path中重复读取,所以尽管我们已经改变了sys.path的内容,import predict仍然维持第一次的引入内容。

      方案1:(已解决)解决方法是尝试删除sys.modules中的缓存内容

 1 class add_path:
 2     def __init__(self, path):
 3         self.path = path
 4 
 5     def __enter__(self):
 6         sys.path.insert(0, self.path)
 7 
 8     def __exit__(self, exc_type, exc_value, traceback):
 9         try:
10             sys.path.remove(self.path)
11             # modules中的缓存名称与import的名称一致,可直接删除对应的缓存
12             # (但前提是该import仅在这一处使用)
13             if "predict" in sys.modules:
14                 del sys.modules['predict']
15         except ValueError:
16             pass     

   方案2:(未实现)引入多进程,每次调用完成后杀死进程,进程推出时会自动清空缓存。

  另外一个思路是,考虑到对于sys.path的修改会在程序执行结束时失效,可以考虑开一个独立的进程引入模型包实现抽取功能,抽取结束后杀死进程。   方法二:使用 python 标准库 importlib 加载特定路径   参考stackoverflow链接,试了下发现这种方法只能导入一个python文件。遗留问题:如何导入一个目录
 1 # 导入指定python文件
 2 def load_package_from_path(pkg_path: str) -> ModuleType:
 3     """
 4     ref: https://stackoverflow.com/a/50395128
 5     """
 6     name = basename(pkg_path)
 7 
 8     spec = util.spec_from_file_location(name, pkg_path)
 9     module = util.module_from_spec(spec)
10     sys.modules[spec.name] = module
11     spec.loader.exec_module(module)
12     
13     return module
  

参考:

  1. python用户文档中的相关内容
  2. python程序导入顺序
  3. 其他参考解决方案

标签:__,python,解决方案,self,py,sys,import,path
From: https://www.cnblogs.com/fresh-star/p/17024413.html

相关文章