第42章- cx_Freeze

在本章中,我们将学习 cx_Freeze ,一组跨平台脚本,设计用于 冻结 以类似于py2exe、pyinstaller等的方式将python脚本转换为可执行文件。我们将使用上一章中的示例冻结一个控制台脚本和一个窗口(即gui)脚本。cx冻结工具是 only 二进制创建工具,现在可以在多个操作系统上同时使用python 2.x和3.x。在本章中,我们将把它与Python2.7一起使用,仅仅是因为我们想直接将它与其他二进制创建工具进行比较。

您可以使用其Windows安装程序之一,通过其提供的Linux RPM,通过源RPM或直接从源代码安装cx_freeze。您也可以使用 pip 安装cx_freeze。

Note: I tested on Windows 7 using Python 2.7.3, wxPython 2.9.4.0 (classic) and cx_Freeze 4.3.2.

开始使用cx_冻结

如cx_Freeze网站上所述,有三种方法可以使用此脚本。第一个是只使用包含的cxfreeze脚本;第二个是创建distutils安装脚本(想想py2exe),您可以将其保存以备将来使用;第三个是使用cxfreeze的内部。我们将重点介绍使用cx-freeze的前两种方法。我们将从控制台脚本开始:

# 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")

所有这些脚本都是使用Michael Foord的 配置 模块。您也可以将其设置为读取配置,但在本例中,我们将跳过该设置。让我们来看看如何用cx冻结来构建二进制文件!根据文档,它只需要在命令行上使用以下字符串(假设您在正确的目录中):

cxfreeze config_1.py --target-dir dirName

假设你有 C:\PythonXX\Scripts 在你的路上。如果没有,则必须修复该问题或键入完全限定的路径。无论如何,如果cxfreeze脚本运行正确,则应该有一个包含以下内容的文件夹:

_images/cx_config.jpg

如您所见,总文件大小应该在5兆字节左右。这很容易。它甚至在不需要我们告诉它的情况下拿起了configobj模块。有18个命令行参数可以传递给cx-freeze来控制它的工作方式。这些范围从包括或排除什么模块、优化、压缩、包括zip文件、路径操作等等。

现在让我们试试更高级的。

高级cx_冻结-使用setup.py文件

首先,我们需要一个脚本来使用。我们将使用前面章节中的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()

现在让我们创建一个 setup.py 采用cx_冻结样式的文件:

# setup.py
from cx_Freeze import setup, Executable

setup(
    name = "wxSampleApp",
    version = "0.1",
    description = "An example wxPython script",
    executables = [Executable("sampleApp.py")]
    )

正如你所看到的,这是一个非常简单的。我们从cx-freeze导入几个类,并向它们传递一些参数。在这种情况下,我们给安装类一个名称、版本、描述和可执行类。可执行类还获得一个参数,即用于创建二进制文件的脚本名。

或者,可以使用cx_freeze的quickstart命令(假定它在系统路径上)在与代码相同的文件夹中创建simple setup.py:

CXFreeze快速启动

要让setup.py生成二进制文件,需要在命令行上执行以下操作:

python setup.py build

运行此操作后,您将得到以下文件夹: buildexe.win32-2.7 .在最后一个文件夹中,我得到了15个文件,总计16.6 MB。运行sampleapp.exe文件时,您会注意到我们搞砸了一些事情。除了我们的GUI,还有一个控制台窗口正在加载!要纠正这个问题,我们需要稍微更改设置文件。看看我们的新产品:

from cx_Freeze import setup, Executable

exe = Executable(
    script="sampleApp.py",
    base="Win32GUI",
    )

setup(
    name = "wxSampleApp",
    version = "0.1",
    description = "An example wxPython script",
    executables = [exe]
    )

首先,我们将可执行类与安装类分离,并将可执行类分配给一个变量。我们还向可执行类添加了第二个参数,即key。该参数被调用 base .通过设置 base="Win32GUI" ,我们可以抑制控制台窗口。cx-freeze网站上的文档显示了可执行类所采用的许多其他选项。

总结

现在您应该知道如何使用cx-freeze创建二进制文件。这很容易做到,而且它比我测试中的bbfreeze快得多。如果您需要为所有主要平台上的python 2.x和3.x创建二进制文件,那么这就是您的工具!