python 打包exe 相关问题
我打包的 A.exe 需要调用B.py 这个模块 , pyinstaller 会把模块一起打包进去 我就没有办法单独修改了, 怎么实现 不一起打包 , 是运行的时候单独调用呢 ,这样我就可以单独修改了 看你调用b.py是咋调用的网上提到的可能的解决方案是把b.py这个文件编译成so文件或者dll文件,再从so或者dll文件中导入需要的函数和模块,我自己也被这个问题所困扰,而且尝试过但未曾解决,最近比较忙,没时间去尝试上面的方法是否可行~~
如果使用import 的方式,是没办法的,因为py文件中的代码想要能运行,就得有python的环境,换句话说,你打包出来的exe程序,如果没有把b.py这个文件编译写入exe文件中,那么这个exe程序在没有python环境的系统里,是无法正常运行的。
那你打包的意意何在?????
本帖最后由 isdkz 于 2022-4-6 09:06 编辑
隐式导入就不会被 pyinstaller 打包,所以我尝试了一下用 __import__ 隐式导入,
不过我发现打包后居然无法导入,所以隐式导入行不通,默认的导入机制也不行,
那只能自己实现导入器:
下面的案例给你参考:
目录结构:
- src
a.py
my_importer.py
test.py
a.py:
def b():
print('你好呀!')
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 执行,不过这种没法隔绝命名空间,容易导致命名空间冲突
isdkz 发表于 2022-4-5 19:31
隐式导入就不会被 pyinstaller 打包,所以我尝试了一下用 __import__ 隐式导入,
不过我发现打包后居然 ...
谢谢您的耐心解答,后面我试了一个比较简单的方法
我的执行 文件放到 ./code/目录下面
main.py 里面加一行
sys.path.append('./code/')就可以了
修改code 里面代码可以直接影响main.exe 的执行结果
如果需要code目录下面的文件也一起打包的话 打包命令加一行 -p “路径” 就可以了 ,
ba21 发表于 2022-4-5 18:49
那你打包的意意何在?????
主程序是打包 成exe 方便其他人使用, 调用的模块不打包 , 方便我修改,
我们公司环境 不是每个人 都会用python的,直接修改导入的模块 不重新编译方便的很多 irx999 发表于 2022-4-10 16:34
谢谢您的耐心解答,后面我试了一个比较简单的方法
我的执行 文件放到 ./code/目录下面
main.py 里面 ...
a.py
-code
b.py
c.py
目录结构↑
代码
a.py 里面
import sys
sys.path.append('./code/')
from b import c
from c import c
这样打包a.py 成 exe 后, b 和 c 不会一起打包, 直接修改code 里面的bc 会影响 a运行的结果 , 这样就方便的很多, 你可以参考一下
irx999 发表于 2022-4-10 16:34
谢谢您的耐心解答,后面我试了一个比较简单的方法
我的执行 文件放到 ./code/目录下面
main.py 里面 ...
我想了解一下你的方法,我根据你说的试了不行,方便加个微信吗? 微信:isdkz_
页:
[1]