|
发表于 2022-4-5 19:31:59
|
显示全部楼层
本帖最后由 isdkz 于 2022-4-6 09:06 编辑
隐式导入就不会被 pyinstaller 打包,所以我尝试了一下用 __import__ 隐式导入,
不过我发现打包后居然无法导入,所以隐式导入行不通,默认的导入机制也不行,
那只能自己实现导入器:
下面的案例给你参考:
目录结构:
- src
a.py
my_importer.py
test.py
a.py:
my_importer.py:
- import sys
- from importlib import abc
- from importlib.machinery import ModuleSpec
- class PathMetaFinder(abc.MetaPathFinder):
- def __init__(self, base):
- self._base = base
-
- def find_spec(self, fullname, path=None, target=None):
- if path is None:
- base = self._base
- else:
- # 不是原定义的路径就直接返回不存在
- if not path.startswith(self._base):
- return None
- base = path
- try:
- loader = PathMetaLoader(base)
- return ModuleSpec(fullname, loader, is_package=loader.is_package(fullname))
- except Exception:
- return None
- class PathMetaLoader(abc.SourceLoader):
- def __init__(self, base):
- self.base = base
- def get_code(self, fullname):
- with open(self.get_filename(fullname), 'rb') as f:
- return f.read()
- def get_data(self):
- pass
- def get_filename(self, fullname):
- return self.base + '\\' + fullname + '.py'
- def install_meta(path):
- finder = PathMetaFinder(path)
- sys.meta_path.append(finder)
复制代码
test.py:
- from my_importer import install_meta
- install_meta('src')
- import a
- a.b()
复制代码
打包命令:
- pyinstaller --add-data src;src test.py
复制代码
对打包后的 src 目录下的 a.py 文件进行修改就可以影响到执行结果
还有一种思路就是读取代码文件,然后用 exec 执行,不过这种没法隔绝命名空间,容易导致命名空间冲突
|
|