分类: Python/Ruby
2009-05-26 14:17:18
py2exe是一個工具程式,可以將python程式轉換成為單一的執行檔案。在某些情況下使用者也許不想安裝整個python套件或是相關的檔 案。透過 py2exe可以將您的工具包裝成單一的執行檔,及數個相關檔案。使用者只要下載這幾個檔案就可以執行該程式了。因為py2exe會自動將該工具的或自動 搜尋您的python程式中所有用到的模組及檔案加以集中包裝至這數個檔案中。
關於py2exe的相關資訊可以在下面的網站中找到。
且讓我用一個範例來說明。我寫了一個wxPython的程式。大家都知道wxPython就是python及wxWidgets的結合。對 於使用者來說, 要同時在他們的電腦中安裝python及wxPython,其實是個蠻沈重的負擔。所以我打算使用py2exe將我寫的工具包裝起來。我的程式總共有兩個 檔案分別是:HtmlConv.py及MainFrame.py。 此時,我們需要準備小小的python程式,透過這個程式來呼叫py2exe包裝我們的程式。我們將這個程式取名為setup.py。其內容如下:
# setup.py
from distutils.core import setup
import py2exe
setup(windows=["HtmlConv.py"])
讓我們來看一下這個檔案的內容。首先,我們可以看到這個python程式引入了distutils這個模組,這個模組是python的標準模 組之一。py2exe其實算是他的擴充模組之一,所以需要載入這個模組中的setup部分。然後,再引入py2exe這個模組。 因為我們的程式很簡單,所以只需要簡單的呼叫setup function。並且在在參數中指定您的主要程式的檔名。您或許會懷疑,我們怎麼不用指定MainFrame.py這個檔案呢?因為 MainFrame.py是被HtmlConv.py這個檔案所import的,py2exe在處理HtmlConv.py時,就會處理到 MainFrame.py了。 有了這三個檔案後,我們需要透過command的方式呼叫python來執行我們的setup.py程式。指令如下:
python.exe setup.py py2exe
您也可以透過下面的命令來瞭解py2exe提供了哪些command line參數:
python.exe setup.py py2exe --help
接著,您會看到有些訊息跑出來,如果都沒有錯誤出現,您會看到出現了兩個新的目錄名為build以及dist。其中build是py2exe再製作過程中的一個暫存目錄。您可以不予理會。而dist目錄中就是您要的東西了。我們的範例中dist目錄產生了下面這些檔案:
HtmlConv.exe
library.zip
python23.dll
w9xpopen.exe
wxc.pyd
xmsw24uh.dll
使用者只需要將這幾個檔案拷貝回去執行HtmlConv.exe就可以執行我們的工具程式。這對於使用者來說,無疑是非常方便的。 現在讓我們重新看看setup.py這個檔案的內容。因為我的工具程式是視窗介面的,不需要出現console視窗。因此,我透過指定 windows=["HtmlConv.py"] 的方式來指定主要檔案。如果您的程式是屬於console介面的,您就應該使用 console=["xxx.py"] 的方式來指定您的程式。此外,py2exe也支援Windows Service及COM元件類型的程式。分別使用下面的方式指定之:
service=["MyService"]
或
com_server=["win32com.server.interp"]
py2exe其實是透過python的modulefinder來找到所需的module,再將他們包裝在一起。您在dist目錄中所看到的 library.zip就是這些module的壓縮檔。不過,也正因為如此,如果是一些您程式中所需要的資料檔,如圖片,音效等等。py2exe並沒有辦 法幫您自動包裝起來。不過,您還是可以透過手動的方式在setup.py中指定setup function的參數來告訴py2exe您還有哪些檔案。假設我們原來程式有一個子目錄名為bmp,下面放了一些程式用到的圖形檔。另外,還有一個子目 錄名為wav,放了一些程式會用到的wav檔案。此時,我們的setup function參數應修改為如下:
setup(windows=["HtmlConv.py"],
data_files=[("bmp",
["bmp/logo.bmp", "bmp/title.gif"]),
("wav",
glob.glob("sounds*.wav"))])
data_files這個參數是一個list,list內的每個元素都是一個pair。pair的第一個元素是您所指定的檔案的目的地。第二個元素 是一個list, 列出了那些檔案的來源。且讓我們仔細看看上面的範例。第一組pair,告訴py2exe在dist目錄下面另外建立一個bmp目錄,並且將原來bmp目錄 中的的logo.bmp及title.gif檔案複製到dist目錄中的bmp子目錄。如果您不希望建立子目錄,可以將目的目錄指定為空白字串。此時, py2exe會將您指定的檔案複製到dist目錄下。 而第二組pair告訴py2exe在dist目錄中建立wav子目錄。然後將sounds目錄中的所有副檔名為wav的檔案拷貝過去。由於我們用了 glob的弁遄C所以別忘了在setup.py中import glob模組。 預設的狀況下,製作出來的執行檔所使用的icon是windows下的預設icon。其實,您可以自己將他修改成其他的icon。首先您先要準備好一個 icon檔案。以上面的例子來說,我們準備一個名為HtmlConv.ico的檔案(檔名未必要與python程式相同)。接著,將上面的範例修改如下:
setup(windows=["HtmlConv.py", {"script":"HtmlConv.py", "icon_resources":[(1, "HtmlConv.ico")]}],
data_files=[("bmp",
["bmp/logo.bmp", "bmp/title.gif"]),
("wav",
glob.glob("sounds*.wav"))])
重新製作執行檔後,該執行檔就會是您所指定的icon囉。py2exe的使用對於會使用python的programmer來說,是非常簡單。而對於使用者而言,不用安裝不必要的東西就可以使用。
py2exe實在是非常值得推薦的工具。
另外一个比较好的例子:
from:http://d887419.spaces.live.com/blog/cns!481a2ec4e1e2501d!682.entry
from distutils.core import setup
import py2exe
setup(
name = 'testGlade',
description = 'Some Test including Glade, Python and GTK in win32',
version = '1.0',
windows = [
{
'script': 'xxxxx.py',
'icon_resources': [(1, "your_program_icon_file.ico")],
}
],
options = {
'py2exe': {
'packages':'encodings',
'includes': 'cairo, pango, pangocairo, atk, gobject', # including the dynamic library
}
},
data_files=[
'xxxxx.glade', # xxxxx.glade is the project file made by Glade
'readme.txt'
]
)
下面是py2exe的help:
>>> help(py2exe)
Help on package py2exe:
NAME
py2exe - builds windows executables from Python scripts
FILE
c:\python25\lib\site-packages\py2exe\__init__.py
DESCRIPTION
New keywords for distutils' setup function specify what to build:
console
list of scripts to convert into console exes
windows
list of scripts to convert into gui exes
service
list of module names containing win32 service classes
com_server
list of module names containing com server classes
ctypes_com_server
list of module names containing com server classes
zipfile
name of shared zipfile to generate, may specify a subdirectory,
defaults to 'library.zip'
py2exe options, to be specified in the options keyword to the setup function
:
unbuffered - if true, use unbuffered binary stdout and stderr
optimize - string or int (0, 1, or 2)
includes - list of module names to include
packages - list of packages to include with subpackages
ignores - list of modules to ignore if they are not found
excludes - list of module names to exclude
dll_excludes - list of dlls to exclude
dist_dir - directory where to build the final files
typelibs - list of gen_py generated typelibs to include (XXX more text n
eeded)
Items in the console, windows, service or com_server list can also be
dictionaries to further customize the build process. The following
keys in the dictionary are recognized, most are optional:
modules (SERVICE, COM) - list of module names (required)
script (EXE) - list of python scripts (required)
dest_base - directory and basename for the executable
if a directory is contained, must be the same for all target
s
create_exe (COM) - boolean, if false, don't build a server exe
create_dll (COM) - boolean, if false, don't build a server dll
bitmap_resources - list of 2-tuples (id, pathname)
icon_resources - list of 2-tuples (id, pathname)
other_resources - list of 3-tuples (resource_type, id, datastring)
PACKAGE CONTENTS
boot_com_servers
boot_common
boot_ctypes_com_server
boot_service
build_exe
mf
py2exe_util
resources (package)
CLASSES
distutils.dist.Distribution
Distribution
class Distribution(distutils.dist.Distribution)
| Methods defined here:
|
| __init__(self, attrs)
|
| ----------------------------------------------------------------------
| Methods inherited from distutils.dist.Distribution:
|
| announce(self, msg, level=1)
|
| dump_option_dicts(self, header=None, commands=None, indent='')
|
| finalize_options(self)
| Set final values for all the options on the Distribution
| instance, analogous to the .finalize_options() method of Command
| objects.
|
| find_config_files(self)
| Find as many configuration files as should be processed for this
| platform, and return a list of filenames in the order in which they
| should be parsed. The filenames returned are guaranteed to exist
| (modulo nasty race conditions).
|
| There are three possible config files: distutils.cfg in the
| Distutils installation directory (ie. where the top-level
| Distutils __inst__.py file lives), a file in the user's home
| directory named .pydistutils.cfg on Unix and pydistutils.cfg
| on Windows/Mac, and setup.cfg in the current directory.
|
| get_command_class(self, command)
| Return the class that implements the Distutils command named by
| 'command'. First we check the 'cmdclass' dictionary; if the
| command is mentioned there, we fetch the class object from the
| dictionary and return it. Otherwise we load the command module
| ("distutils.command." + command) and fetch the command class from
| the module. The loaded class is also stored in 'cmdclass'
| to speed future calls to 'get_command_class()'.
|
| Raises DistutilsModuleError if the expected module could not be
| found, or if that module does not define the expected class.
|
| get_command_list(self)
| Get a list of (command, description) tuples.
| The list is divided into "standard commands" (listed in
| distutils.command.__all__) and "extra commands" (mentioned in
| self.cmdclass, but not a standard command). The descriptions come
| from the command class attribute 'description'.
|
| get_command_obj(self, command, create=1)
| Return the command object for 'command'. Normally this object
| is cached on a previous call to 'get_command_obj()'; if no command
| object for 'command' is in the cache, then we either create and
| return it (if 'create' is true) or return None.
|
| get_command_packages(self)
| Return a list of packages from which commands are loaded.
|
| get_option_dict(self, command)
| Get the option dictionary for a given command. If that
| command's option dictionary hasn't been created yet, then create it
| and return the new dictionary; otherwise, return the existing
| option dictionary.
|
| handle_display_options(self, option_order)
| If there were any non-global "display-only" options
| (--help-commands or the metadata display options) on the command
| line, display the requested info and return true; else return
| false.
|
| has_c_libraries(self)
|
| has_data_files(self)
|
| has_ext_modules(self)
|
| has_headers(self)
|
| has_modules(self)
|
| has_pure_modules(self)
|
| has_scripts(self)
|
| is_pure(self)
|
| parse_command_line(self)
| Parse the setup script's command line, taken from the
| 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
| -- see 'setup()' in core.py). This list is first processed for
| "global options" -- options that set attributes of the Distribution
| instance. Then, it is alternately scanned for Distutils commands
| and options for that command. Each new command terminates the
| options for the previous command. The allowed options for a
| command are determined by the 'user_options' attribute of the
| command class -- thus, we have to be able to load command classes
| in order to parse the command line. Any error in that 'options'
| attribute raises DistutilsGetoptError; any error on the
| command-line raises DistutilsArgError. If no Distutils commands
| were found on the command line, raises DistutilsArgError. Return
| true if command-line was successfully parsed and we should carry
| on with executing commands; false if no errors but we shouldn't
| execute commands (currently, this only happens if user asks for
| help).
|
| parse_config_files(self, filenames=None)
|
| print_command_list(self, commands, header, max_length)
| Print a subset of the list of all commands -- used by
| 'print_commands()'.
|
| print_commands(self)
| Print out a help message listing all available commands with a
| description of each. The list is divided into "standard commands"
| (listed in distutils.command.__all__) and "extra commands"
| (mentioned in self.cmdclass, but not a standard command). The
| descriptions come from the command class attribute
| 'description'.
|
| reinitialize_command(self, command, reinit_subcommands=0)
| Reinitializes a command to the state it was in when first
| returned by 'get_command_obj()': ie., initialized but not yet
| finalized. This provides the opportunity to sneak option
| values in programmatically, overriding or supplementing
| user-supplied values from the config files and command line.
| You'll have to re-finalize the command object (by calling
| 'finalize_options()' or 'ensure_finalized()') before using it for
| real.
|
| 'command' should be a command name (string) or command object. If
| 'reinit_subcommands' is true, also reinitializes the command's
| sub-commands, as declared by the 'sub_commands' class attribute (if
| it has one). See the "install" command for an example. Only
| reinitializes the sub-commands that actually matter, ie. those
| whose test predicates return true.
|
| Returns the reinitialized command object.
|
| run_command(self, command)
| Do whatever it takes to run a command (including nothing at all,
| if the command has already been run). Specifically: if we have
| already created and run the command named by 'command', return
| silently without doing anything. If the command named by 'command'
| doesn't even have a command object yet, create one. Then invoke
| 'run()' on that command object (or an existing one).
|
| run_commands(self)
| Run each command that was seen on the setup script command line.
| Uses the list of commands found and cache of command objects
| created by 'get_command_obj()'.
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from distutils.dist.Distribution:
|
| common_usage = "Common commands: (see '--help-commands' for more...'\n..
.
|
| display_option_names = ['help_commands', 'name', 'version', 'fullname'..
.
|
| display_options = [('help-commands', None, 'list all available command..
.
|
| global_options = [('verbose', 'v', 'run verbosely (default)', 1), ('qu..
.
|
| negative_opt = {'quiet': 'verbose'}
DATA
__version__ = '0.6.9'
VERSION
0.6.9