鱼C论坛

 找回密码
 立即注册
查看: 2056|回复: 8

python 打包exe 相关问题

[复制链接]
发表于 2022-4-5 18:03:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我打包的 A.exe 需要调用B.py 这个模块 , pyinstaller 会把模块一起打包进去 我就没有办法单独修改了, 怎么实现 不一起打包 , 是运行的时候单独调用呢 ,这样我就可以单独修改了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-4-5 18:18:43 From FishC Mobile | 显示全部楼层
看你调用b.py是咋调用的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-5 18:32:43 | 显示全部楼层

网上提到的可能的解决方案是把b.py这个文件编译成so文件或者dll文件,再从so或者dll文件中导入需要的函数和模块,我自己也被这个问题所困扰,而且尝试过但未曾解决,最近比较忙,没时间去尝试上面的方法是否可行~~
如果使用import 的方式,是没办法的,因为py文件中的代码想要能运行,就得有python的环境,换句话说,你打包出来的exe程序,如果没有把b.py这个文件编译写入exe文件中,那么这个exe程序在没有python环境的系统里,是无法正常运行的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-5 18:49:28 | 显示全部楼层
那你打包的意意何在?????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-5 19:31:59 | 显示全部楼层
本帖最后由 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 执行,不过这种没法隔绝命名空间,容易导致命名空间冲突
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-10 16:34:00 | 显示全部楼层
isdkz 发表于 2022-4-5 19:31
隐式导入就不会被 pyinstaller 打包,所以我尝试了一下用 __import__ 隐式导入,

不过我发现打包后居然 ...

谢谢您的耐心解答,  后面我试了一个比较简单的方法
我的执行 文件放到 ./code/目录下面
main.py 里面加一行
sys.path.append('./code/')  就可以了
修改code 里面代码可以直接影响main.exe 的执行结果
如果需要code目录下面的文件也一起打包的话 打包命令加一行 -p “路径” 就可以了 ,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-10 16:35:49 | 显示全部楼层
ba21 发表于 2022-4-5 18:49
那你打包的意意何在?????

主程序是打包 成exe 方便其他人使用, 调用的模块不打包 , 方便我修改,
我们公司环境 不是每个人 都会用python的,直接修改导入的模块 不重新编译方便的很多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-10 16:41:15 | 显示全部楼层
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  运行的结果 , 这样就方便的很多  , 你可以参考一下

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-10 16:44:57 | 显示全部楼层
irx999 发表于 2022-4-10 16:34
谢谢您的耐心解答,  后面我试了一个比较简单的方法
我的执行 文件放到 ./code/目录下面
main.py 里面 ...

我想了解一下你的方法,我根据你说的试了不行,方便加个微信吗? 微信:isdkz_
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 04:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表