第41章-B冻结

这个 B冻结 包还允许我们创建二进制文件,但只能在Linux和Windows上创建。在Linux上创建二进制文件时,结果将只在具有相同硬件体系结构和libc版本的计算机上运行,这限制了它在Linux上的实用性。还应该注意的是,bbfreeze只适用于Python版本2.4-2.7。您可以使用Easy_Install或PIP将bbFreeze软件包安装到您的系统上。bbfreeze包包含了egg支持,因此它可以在二进制文件中包含egg依赖项,而不是py2exe。您还可以一次冻结多个脚本,包括Python解释器等等。

bbFreeze入门

您可以使用easy-install下载和安装bbfreeze,也可以直接从python包索引(pypi)下载其源文件或egg文件。在本文中,我们将尝试在一个简单的配置文件生成器脚本上使用它,并且还将在Py2Exe一章中的wxpython程序上使用它。

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

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

这个脚本有几个非常没有意义的函数,但是为了便于说明,我们将把它们放在里面。根据bbfreeze文档,我们应该能够创建一个二进制文件,并在命令行中键入以下字符串:

bb-freeze config_1.py

假设你有 C:\Python27\Scripts 在你的路上。如果不这样做,则需要键入完整的路径(即 C:\Python27\Scripts\bb-freeze config_1.py )。如果你运行这个,你应该看到一个名为 dist 创建。这是我跑步后的样子 config_1.exe

_images/bb_config.jpg

您会注意到,当您运行可执行文件时,它会创建一个名为 sampleconfig2.ini .您可能会看到关于 Pywin32 未安装程序包。您可以忽略警告或下载并安装pywin32。

现在我们准备好继续,并尝试从使用wxpython的代码创建可执行文件!

使用bbfreeze的高级配置

bbfreeze的pypi页面(也是它的主页)几乎没有文档。但是,页面确实指出,使用bbfreeze的首选方法是使用很少的脚本。我们将尝试使用前面提到的wxpython示例创建二进制文件。这是WX代码:

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()

现在让我们创建一个简单的冻结脚本!

# bb_setup.py
from bbfreeze import Freezer

f = Freezer(distdir="bb-binary")
f.addScript("sampleApp.py")
f()

首先,我们导入 冷冻室 类从 B冻结 包裹。冷冻室接受三个参数:目标文件夹,一个 包括 不可更改和 排除 可Iterable(即元组或列表)。为了了解bbfreeze只使用默认值的效果,我们省略了include和excludes元组/列表。一旦有了一个冷冻器对象,就可以通过调用冷冻器对象名的add script方法来添加脚本。然后你只需要调用对象(即 f()

Note: You may see a warning about bb_freeze not being able to find "MSVCP90.dll" or similar. If you see that message, you may need to include it explicitly or add it as a dependency when you create an installer. We will be learning about how to create an installer in a later chapter.

要运行此脚本,只需执行以下操作:

python bb_setup.py

当我运行这个脚本时,它创建了一个名为 bb-binary 其中包含19个文件,重17.2 MB。当我跑的时候 sampleApp.exe 文件,它运行得很好,主题也很好,但是它也有一个控制台屏幕。我们需要编辑一下我们的脚本来解决这个问题:

# bb_setup2.py
from bbfreeze import Freezer

includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
            'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
            'Tkconstants', 'Tkinter']

bbFreeze_Class = Freezer('dist', includes=includes, excludes=excludes)

bbFreeze_Class.addScript("sampleApp.py", gui_only=True)

bbFreeze_Class.use_compression = 0
bbFreeze_Class.include_py = True
bbFreeze_Class()

如果你运行这个,你应该以一个 dist 文件夹包含大约19个文件,但大小略有不同,为19.6 MB。注意,我们在addscript方法中添加了第二个参数:gui_only=true。这使得那个恼人的控制台消失了。我们还将压缩设置为零(无压缩),并包括Python解释器。但是,打开压缩只会将结果减少到17.2 MB。

BBFreeze软件包还处理“食谱”,包括几个例子,但是它们也没有很好的文档记录。作为一种锻炼,你可以自己研究它们。

总结

现在,您应该了解使用bbfreeze从程序创建二进制文件的基本知识。我注意到,在我的机器上运行bbfreeze时,与py2exe相比,生成wxpython可执行文件的速度要慢得多。这是在确定要使用哪种工具来创建二进制文件时必须进行的实验之一。