第43章-PyInstaller

pyinstaller是我们将要寻找的最后一个创建二进制文件的工具。它支持python 2.4-2.7。我们将继续使用简单的控制台和wxpython GUI脚本进行测试。pyinstaller应该在Windows、Linux、Mac、Solaris和AIX上工作。对Solaris和AIX的支持是实验性的。pyinstaller支持代码签名(windows)、 egg 、隐藏导入、单个可执行文件、单个目录等等!

注意:我使用python 2.7.3、wxpython2.9.4.0(经典)和pyinstaller 2.1在Windows7上进行了测试。

PyInstaller入门

要安装pyinstaller,可以下载tarball或zip文件中的源代码,将其解压缩并运行 setup.py 文件:

python setup.py install

也可以使用pip安装pyinstaller。我们将从一小段配置创建代码开始:

# config_1.py
import configobj

def createConfig(configFile):
    """
    Create the configuration file
    """
    config = configobj.ConfigObj()
    inifile = configFile
    config.filename = inifile
    config['server'] = "http://www.google.com"
    config['username'] = "mike"
    config['password'] = "dingbat"
    config['update interval'] = 2
    config.write()

def getConfig(configFile):
    """
    Open the config file and return a configobj
    """
    return configobj.ConfigObj(configFile)

def createConfig2(path):
    """
    Create a config file
    """
    config = configobj.ConfigObj()
    config.filename = path
    config["Sony"] = {}
    config["Sony"]["product"] = "Sony PS3"
    config["Sony"]["accessories"] = ['controller', 'eye', 'memory stick']
    config["Sony"]["retail price"] = "$400"
    config.write()

if __name__ == "__main__":
    createConfig2("sampleConfig2.ini")

现在让我们尝试创建一个可执行文件!您应该可以这样做,让pyinstaller工作:

pyinstaller config_1.py

当我运行此程序时,出现以下错误:

Error: PyInstaller for Python 2.6+ on Windows needs pywin32.
Please install from http://sourceforge.net/projects/pywin32/

要在Windows上使用pyinstaller,需要安装 PyWi32 第一!一旦安装了pywin32,请尝试重新运行该命令。您应该会看到发送到屏幕的大量输出,您还应该看到脚本旁边出现了这两个文件夹: 建造dist .如果你进入 dist 文件夹,然后放入其 config_1 文件夹中,您应该看到如下内容:

_images/pyinstaller.jpg

当我运行可执行文件时,它按照应该的方式创建了配置文件。你会注意到pyinstaller能够 配置 你不需要告诉它。

pyinstaller和wxpython

现在,让我们尝试从一个简单的wxpython脚本创建一个二进制文件。这是我们在前几章中使用的wxpython代码:

import wx

class DemoPanel(wx.Panel):
    """"""

    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        labels = ["Name", "Address", "City", "State", "Zip",
                  "Phone", "Email", "Notes"]

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        lbl = wx.StaticText(self, label="Please enter your information here:")
        lbl.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
        mainSizer.Add(lbl, 0, wx.ALL, 5)
        for lbl in labels:
            sizer = self.buildControls(lbl)
            mainSizer.Add(sizer, 1, wx.EXPAND)
        self.SetSizer(mainSizer)
        mainSizer.Layout()

    def buildControls(self, label):
        """
        Put the widgets together
        """
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        size = (80,40)
        font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)

        lbl = wx.StaticText(self, label=label, size=size)
        lbl.SetFont(font)
        sizer.Add(lbl, 0, wx.ALL|wx.CENTER, 5)
        if label != "Notes":
            txt = wx.TextCtrl(self, name=label)
        else:
            txt = wx.TextCtrl(self, style=wx.TE_MULTILINE, name=label)
        sizer.Add(txt, 1, wx.ALL, 5)
        return sizer

class DemoFrame(wx.Frame):
    """
    Frame that holds all other widgets
    """

    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "Py2Exe Tutorial",
                          size=(600,400)
                          )
        panel = DemoPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()

如果你执行 PY安装程序 命令对这个脚本,您将看到更多的输出发送到屏幕。它将创建23个文件,总计19.4 MB。当您运行 sampleApp.exe 除了您的GUI之外,它还显示一个控制台窗口,这不是我们想要的。最简单的修复方法是使用 -w 命令,指示pyinstaller取消控制台窗口:

pyinstaller -w sampleApp.py

pyinstaller包有许多命令行选项,可以用来更改pyinstaller处理程序的方式。无论何时运行pyinstaller,它都会创建一个 spec 用于处理程序的文件。如果要保存spec文件的副本以帮助您更好地了解pyinstaller正在做什么,可以使用以下命令执行此操作:

pyi-makespec sampleApp.py

您可以将相同的命令传递给 pyi-makespec 正如您对pyinstaller所做的那样,它将适当地更改规范。以下是用上一个命令创建的规范的内容:

# -*- mode: python -*-
a = Analysis(['sampleApp.py'],
             pathex=['c:\\py101\\wxpy'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='sampleApp.exe',
          debug=False,
          strip=None,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name='sampleApp')

在早期版本的pyinstaller中,您实际上会创建spec文件并直接对其进行编辑。现在,除非您需要一些真正特殊的东西,否则您可以通过使用标志来生成正确的规范。请务必阅读文档以了解完整的详细信息,因为有许多标志,并且对它们进行描述都超出了本章的范围。

总结

这结束了我们对pyinstaller的快速浏览。我希望你能在你的python二进制代码中发现这一点。PyInstaller项目有很好的文档记录,值得您花时间检查。