我正在尝试使用cxfreeze将我的Python脚本构建到.exe
文件中。但是,我的脚本使用了一些外部数据文件,这些文件未打包到创建的libary.zip
文件中。
例如,我的脚本位于src/
,外部数据位于src/data/
。我在include_files
中指定了build_exe_options
属性,但这只将目录和文件复制到构建目录中;它不会将它们添加到library.zip
,这是脚本最终查找文件的地方。
即使我进入创建的library.zip
并手动添加data
目录,我也会收到同样的错误。知道如何让cxfreeze
适当地打包这些外部资源吗?
setup.py
from cx_Freeze import setup, Executable
build_exe_options = {"includes" : ["re"], "include_files" : ["data/table_1.txt", "data/table_2.txt"]}
setup(name = "My Script",
version = "0.8",
description = "My Script",
options = { "build_exe" : build_exe_options },
executables = [Executable("my_script.py")])
fileutil.py (尝试读取资源文件的地方)
def read_file(filename):
path, fl = os.path.split(os.path.realpath(__file__))
filename = os.path.join(path, filename)
with open(filename, "r") as file:
lines = [line.strip() for line in file]
return [line for line in lines if len(line) == 0 or line[0] != "#"]
......跟......打电话。
read_file("data/table_1.txt")
错误追溯
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\cx_Freeze\initscripts\Console3.py", line 2
7, in <module> exec(code, m.__dict__)
File "my_script.py", line 94, in <module>
File "my_script.py", line 68, in run
File "C:\workspaces\py\test_script\src\tables.py", line 12, in load_data
raw_gems = read_file("data/table_1.txt")
File "C:\workspaces\py\test_script\src\fileutil.py", line 8, in read_file
with open(filename, "r") as file:
FileNotFoundError: [Errno 2] No such file or directory:
'C:\\workspaces\\py\\test_script\\src\\build\\exe.win32-3.3\\library.zip\\data/table_1.txt'
答案 0 :(得分:3)
以下结构对我有用:
|-main.py
|-src
|-utils.py (containing get_base_dir())
|-data
然后引用你的数据总是相对于你通过src目录中的以下函数收到的main.py的位置:
import os, sys, inspect
def get_base_dir():
if getattr(sys,"frozen",False):
# If this is running in the context of a frozen (executable) file,
# we return the path of the main application executable
return os.path.dirname(os.path.abspath(sys.executable))
else:
# If we are running in script or debug mode, we need
# to inspect the currently executing frame. This enable us to always
# derive the directory of main.py no matter from where this function
# is being called
thisdir = os.path.dirname(inspect.getfile(inspect.currentframe()))
return os.path.abspath(os.path.join(thisdir, os.pardir))
如果您根据cx_Freeze文档包含数据,它将与.exe
文件位于同一目录中(即不在zip文件中),这将与此解决方案一起使用。