python-使用cx_freeze 4.3.1冻结h5py 2.4时出错
作者:互联网
我试图用cx_Freeze冻结Python脚本.该脚本使用了h5py v2.4.0b1.当我运行cx_Freeze创建的可执行文件时,得到以下回溯:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>
exec(code, m.__dict__)
File "main.py", line 7, in <module>
from xman import xmanLogging, xmanManager, xmanInfo
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\__init__.py", line 3, in <
module>
from .xmlHandler import barMAN, xmlClass
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\xmlHandler\__init__.py", l
ine 7, in <module>
from . import barMAN, xmlClass
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2284, in _handle_fromlist
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 321, in _call_with_frames_removed
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\xmlHandler\xmlClass.py", l
ine 25, in <module>
from xman.COMInterface import COMmanager
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\COMInterface\__init__.py",
line 7, in <module>
from . import COMmanager
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2284, in _handle_fromlist
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 321, in _call_with_frames_removed
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "d:\user\aagbds\Programmierung\Python\EclipseProjects\xMAN\src\xman\COMInterface\COMmanager.py
", line 20, in <module>
import logging, win32com.client , pythoncom, pywintypes, h5py, \
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2237, in _find_and_load
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 2226, in _find_and_load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1191, in _load_unlocked
File "X:\Python34-x32\lib\importlib\_bootstrap.py", line 1161, in _load_backward_compatible
File "C:\Python34\lib\site-packages\h5py\__init__.py", line 10, in <module>
from h5py import _errors
ImportError: cannot import name '_errors'
我正在使用Python 3.4.2-32位.有人有主意吗?
解决方法:
我花了两天时间试图弄清楚这一点.
我正在使用64位python 2.7,但是在Windows,Ubuntu 14和Mac OS 10.9和10.10中却遇到了与您完全相同的错误.我也在使用h5py 2.4.0和cx_Freeze 4.3.4.
对我来说,解决方案如下:
我不得不将load_h5py的cx_Freeze中的hooks.py更改为:
def load_h5py(finder, module):
"""h5py module has a number of implicit imports"""
finder.IncludeModule('h5py.defs')
finder.IncludeModule('h5py.utils')
finder.IncludeModule('h5py._proxy')
try:
finder.IncludeModule('h5py._errors')
finder.IncludeModule('h5py.h5ac')
except:
pass
try:
finder.IncludeModule('h5py.api_gen')
except:
pass
另外,似乎某些h5py.*.so的引用依赖项与
@ loader_path / .dylibs / libhdf5.8.dylib
cx_freeze不会重写它.
我必须修改cx_freeze中的代码(实际上,我将代码复制到了setup.py中,并在主setup(….)调用后立即对其进行了调用以对构建中的所有文件进行后期处理)
# this is a straight copy paste from macdist.py in the cx_Freeze code
def setRelativeReferencePaths(binDir):
""" For all files in Contents/MacOS, check if they are binaries
with references to other files in that dir. If so, make those
references relative. The appropriate commands are applied to all
files; they will just fail for files on which they do not apply."""
files = []
for root, dirs, dir_files in os.walk(binDir):
files.extend([os.path.join(root, f).replace(binDir + "/", "")
for f in dir_files])
for fileName in files:
# install_name_tool can't handle zip files or directories
filePath = os.path.join(binDir, fileName)
if fileName.endswith('.zip'):
continue
# ensure write permissions
mode = os.stat(filePath).st_mode
if not (mode & stat.S_IWUSR):
os.chmod(filePath, mode | stat.S_IWUSR)
# let the file itself know its place
subprocess.call(('install_name_tool', '-id',
'@executable_path/' + fileName, filePath))
# find the references: call otool -L on the file
otool = subprocess.Popen(('otool', '-L', filePath),
stdout=subprocess.PIPE)
references = otool.stdout.readlines()[1:]
for reference in references:
# find the actual referenced file name
referencedFile = reference.decode().strip().split()[0]
if referencedFile.startswith('@loader_path/.dylibs/'):
# this file is likely an hdf5 file
print "Found hdf5 file {} referencing {}".format(filePath, referencedFile)
elif referencedFile.startswith('@'):
# the referencedFile is already a relative path
continue
path, name = os.path.split(referencedFile)
# some referenced files have not previously been copied to the
# executable directory - the assumption is that you don't need
# to copy anything fro /usr or /System, just from folders like
# /opt this fix should probably be elsewhere though
# if (name not in files and not path.startswith('/usr') and not
# path.startswith('/System')):
# print(referencedFile)
# self.copy_file(referencedFile,
# os.path.join(self.binDir, name))
# files.append(name)
# see if we provide the referenced file;
# if so, change the reference
if name in files:
newReference = '@executable_path/' + name
subprocess.call(('install_name_tool', '-change',
referencedFile, newReference, filePath))
标签:cx-freeze,h5py,python 来源: https://codeday.me/bug/20191028/1955741.html