Pyinstaller程序

时间:2016-11-28 08:42:48

标签: python python-3.x import pyinstaller

我正在尝试一种简单的方法来更新我正在处理的程序,只需将替换.py文件放在一个文件夹中,然后将其放在sys.path列表的顶部,以便所有import语句将首先检查该文件夹而不是我的顶级目录,导入较新的.py文件,而不是最初使用PyInstaller构建程序的文件。现在,如果我使用这段代码:

    import sys,os
    bundlePath = 'c:/tests/importTest' 
    print ("Bundle path: {}".format(bundlePath))
    importPath = bundlePath + '/uploads'
    sys.path.insert(0,importPath)
    print ("Import path: {}".format(sys.path[0]))
    os.chdir(sys.path[0])
    import testyTastery
    print(testyTastery.message)

我的Python IDE或通过命令行运行此脚本将打印来自uploads/testyTastery.py的消息(顶级目录中还有一个testyTastery.py)。但是,当我将第2行更改为bundlePath = sys.path[1]时(因为PyInstaller中的构建将顶级目录放在sys.path [1]中,至少在Windows中,sys.path [0]指向PyInstaller的base_library.zip创建)并将其构建到PyInstaller的文件夹包中(确保复制uploads/testyTastery.py或将其包含在.spec文件中),我从testyTastery.py脚本获取消息,而不是上传/ testyTastery.py脚本。

有关如何轻松改变这一点的任何想法?为了清楚起见,在改变第二行之后,前两个print语句在使用PyInstaller编译之前和之后运行它都会产生相同的输出。

我不知道,但也许它与PyInstaller有关,在查看sys.path进行导入之前总是查看它打包的文件?

编辑:要清楚,如果我在没有可用文件的情况下进行构建,那么之后将文件放在相应的文件夹中,导入优先级就像在命令行/ IDE中一样。这告诉我,PyInstaller打包的文件在导入层次结构中更高。

1 个答案:

答案 0 :(得分:1)

我终于找到了解决这个问题的方法。为了清楚起见,最初的问题是用PyInstaller打包文件(在文件夹选项中),稍后只需放入文件来替换最初打包的文件。因为PyInstaller将其加载文件的方法插入到sys.meta_path中,所以需要在PyInstaller之前安装自己的自定义导入方法。这就是我所拥有的(改变系统路径的顺序是因为PyInstaller也将sys.path [0]更改为zip文件,sys.path [1]是你真正希望在顶部的sys.path链如果您正在执行此操作或在程序中使用sys.path [0]:

import os
import sys
sys.path = [sys.path[1]] + [sys.path[0]] + sys.path[2:]
from importlib.machinery import SourceFileLoader

class MyImporter(object):
    def find_module(self, module_name, package_path):
        print ('entered again')
        if os.path.exists("{}/{}.py".format(sys.path[0],module_name)):
            return SourceFileLoader(module_name,"{}/{}.py".format(sys.path[0],module_name))
        else:
            return None
    def load_module(self, module_name):
        if os.path.exists("{}/{}.py".format(sys.path[0],module_name)):
            return SourceFileLoader(module_name,"{}/{}.py".format(sys.path[0],module_name)).load_module()
        else:
            return None
sys.meta_path.insert(1,MyImporter())

如果你在PyInstaller导入的主文件中执行此操作,那么整个程序将搜索sys.path [0](当然,在搜索之前向系统路径添加更多文件夹并搜索它们也是微不足道的)用于PyInstaller打包的模块。