PIL/Pillow - ValueError: py.__spec__ is not set

3

我正在尝试使用py2exe制作 exe 文件。之前,这个过程进行得很好 - 我还拥有我编辑的代码的工作 exe 文件。然而,当我现在尝试运行下面的代码时,在 Anaconda 命令提示符中出现了“ValueError: py.__spec__ is not set”的错误。尝试创建另一个程序的 exe 文件会成功。

不幸的是,我保存了早期可工作的程序的旧版本,但是我已经根据记忆将新程序恢复到了旧版本,但它仍然无法正常工作。为什么会发生这种情况呢?我认为这与 PIL 模块有关,因为那是我的其他程序与其正确转换为 exe 的唯一区别。此外,注释掉 PIL 模块也会导致成功转换。但是,这意味着该程序不能用于原来的目的。

py2exe setup.py 代码:

from distutils.core import setup

import py2exe

setup(console=['resizeImg.py'])

我的程序:

from PIL import Image
import os, sys
from pathlib import Path

while True:
    # Warning message for users
    print('')
    print('IMPORTANT!!!'.center(len('IMPORTANT!!!')+12,'*'))
    print('If a file exists in the same name in destination folder, \
it will be IRREVERSIBLY OVERWRITTEN!')
    print('*'*(len('IMPORTANT!!!')+12))
    
    print('\nEnter full paths for source and destination. \
          \nEnter q to quit.')
          
    spath = input('Source path: ')
    if spath == 'q':
        sys.exit()
    dpath = input('Destination path: ')
    if dpath == 'q':
        sys.exit()
    elif dpath == spath:
        Path(spath,'scaledImages').mkdir(exist_ok=True)
        dpath = str(Path(spath,'scaledImages'))
    htsize = int(input('Height dimension: '))
    if htsize == 'q':
        sys.exit()
    
    os.chdir(Path(spath))
    optSize = htsize
    
    for filename in os.listdir('.'):
        print (filename)
        if not (filename.endswith('.jpeg') or filename.endswith('.jpg') or filename.endswith('.png') or filename.endswith('.bmp')):
            continue
        else:
            im = Image.open(filename)
            width, height = im.size
            
        if height > optSize:
            # commented out to remove width height check
            # if width > height:
            #     height = int((optSize / width) * height)
            #     width = optSize
                
            # else:
            #     width = int((optSize / height) * width)
            #     height = optSize
            width = int((optSize / height) * width)
            height = optSize
            
                
            print('')
            print(f'Resizing {filename} ...')
            
            im = im.resize((width,height))
            
            im.save(Path(dpath) / filename)
            
        else:
            im.save(Path(dpath) / filename)
            
        print('New dimension: ' + str(width) + ' x ' + str(height))
            
    print('\nRescaling complete. Rescaled images saved in: ' + \
          dpath + '\n')
    quitPrompt = input('q to quit; any other input for new search: ')
    if quitPrompt.lower() == 'q':
        sys.exit()

当我尝试在Anaconda命令提示符中运行'python setup.py py2exe'时,我需要执行py2exe。
running py2exe
Traceback (most recent call last):
  File "setup.py", line 11, in <module>
    setup(console=['resizeImg.py'])
  File "C:\Users\hamis\anaconda3\lib\distutils\core.py", line 148, in setup
    dist.run_commands()
  File "C:\Users\hamis\anaconda3\lib\distutils\dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "C:\Users\hamis\anaconda3\lib\distutils\dist.py", line 985, in run_command
    cmd_obj.run()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 192, in run
    self._run()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\distutils_buildexe.py", line 272, in _run
    builder.analyze()
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\runtime.py", line 177, in analyze
    target.analyze(mf)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\runtime.py", line 78, in analyze
    modulefinder.run_script(self.script)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 62, in run_script
    self._scan_code(mod.__code__, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 393, in _scan_code
    self._scan_code(c, mod)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 109, in import_hook
    self._handle_fromlist(module, fromlist, caller)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 180, in _handle_fromlist
    self._gcd_import('{}.{}'.format(mod.__name__, x))
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 348, in _find_and_load
    self._scan_code(module.__code__, module)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 386, in _scan_code
    self.safe_import_hook(name, mod, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 122, in safe_import_hook
    self.import_hook(name, caller, fromlist, level)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 104, in import_hook
    module = self._gcd_import(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 258, in _gcd_import
    return self._find_and_load(name)
  File "C:\Users\hamis\anaconda3\lib\site-packages\py2exe\mf34.py", line 303, in _find_and_load
    spec = importlib.util.find_spec(name, path)
  File "C:\Users\hamis\anaconda3\lib\importlib\util.py", line 111, in find_spec
    raise ValueError('{}.__spec__ is not set'.format(name)) from None
ValueError: py.__spec__ is not set
2个回答

3

我使用的是Python 3.8Spyder 4.1.4

当您使用库py2exe创建exe时,有时会出现模块导入问题。如果您找到了错误的模块,可以在setup.py中将其排除。

  • 如何在创建exe时查找导入过程中出现的错误模块? :

库py2exe使用位于导入库importlib中的脚本util.py来构建导入器。在此脚本中,在函数find_spec()中的else语句中添加一个print(module)即可:

else:
    module = sys.modules[fullname]
    print(module)
    if module is None:
        return None

在添加打印语句后,当您尝试创建.exe文件时,在控制台中,您将看到导入的模块。 当出现如下错误时:
ValueError: py.__spec__ is not set

搜索最后导入的模块并在 setup.py 中排除它。

逐个模块地操作,这样就不会再出现错误了。

  • 如何排除一个模块?:

要在 setup.py 中排除一个错误的模块,请将错误模块的名称写入选项中。如果需要,还可以排除 dll_excludes。

下面是我已经排除了你脚本中的错误模块:

from distutils.core import setup

import py2exe

setup(options = {"py2exe":{   "excludes": ["_pytest","qtpy"] } },
      console = ['resizeImg.py'])

我不确定这是否是解决您问题的好方法,但在我将py转换为exe时,我的脚本可以正常工作。


1
非常感谢,pont_!我还没有完全实现和尝试这个编辑。但它非常有用,不仅仅是针对这个问题。让我更好地理解了这些库的工作原理。 - etchmd

3

p2exe只支持Python版本3.6及以下

如果您成功将Python运行时降级,p2exe应该可以编译。否则,您需要使用替代库,比如pyinstaller。


谢谢,Shivaji。这可能是原因,因为我记得那个时候升级了Python。我已经开始使用pyinstaller,它对我来说似乎工作得很好。 - etchmd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接