我有一个非常简单的Python程序,使用了“祝福”。它可以与Win10 Python解释器正常工作,但与Pyinstaller打包时报告错误,并且终端控制代码将被忽略。这是代码:
from blessed import Terminal
t = Terminal()
print(t.bright_green('Hello world'))
字符串“ Hello world”应该在控制台上以亮绿色显示。 Pyinstaller完成没有错误,并且当我运行.exe时,出现消息:
terminal.py:222:用户警告:无法设置termterm(kind ='vtwin10'):找不到终端vtwin10
然后以默认的终端颜色显示“ Hello world”。
看起来Pyinstaller并未在构建中包含解释器发现没有问题的内容。我在Anaconda3安装文件夹中找到了一个vtwin10.py文件,位于:
C:\ Anaconda3 \ Lib \ site-packages \ jinxed \ terminfo
我查看了受祝福的库的terminal.py文件中的引用错误。这是代码:
try:
curses.setupterm(self._kind, self._init_descriptor)
except curses.error as err:
warnings.warn('Failed to setupterm(kind={0!r}): {1}'
.format(self._kind, err))
所以看起来self._kind被设置为'vtwin10'。 terminal.py中有条件导入,如下所示:
if platform.system() == 'Windows':
import jinxed as curses # pylint: disable=import-error
HAS_TTY = True
((我很幽默。)看起来jinxed包已在代码中显式导入,并替换了curses包。但是以某种方式缺少vtwin10定义。
我发现Jinxed中的setupterm()并进行了更深的挖掘,以查找错误消息的来源。在此代码中:
try:
self.terminfo = importlib.import_module('jinxed.terminfo.%s' % term.replace('-', '_'))
except ImportError:
raise error('Could not find terminal %s' % term)
这是我卡住的地方。看起来这段代码无法在jinxed库中找到vtwin10.py文件。有谁知道如何强制Pyinstaller包含vtwin10终端定义以进行诅咒?我猜这是问题所在。
非常感谢。
最后想通了。在jinxed库中,代码行:
importlib.import_module('jinxed.terminfo.%s' % term.replace('-', '_'))
动态加载库模块。 Pyinstaller无法打包动态导入的模块。因此,要解决此问题,我需要使用--hidden-import选项指定模块。语法如下:
pyinstaller --hidden-import=jinxed.terminfo.vtwin10 --onefile test.py
程序的工作方式与解释器一样。它可以工作,但是我担心这会破坏任何应该具有的平台独立性jinxed
。我可以强制导入vtwin10.py
模块,它将在win10
平台上运行。但是,编写jinxed
的方式会找出Windows平台,然后动态加载所需的terminfo
模块。 jinxed.terminfo
目录中有许多它们。 --hidden-import
的通配符不起作用,因此唯一的选择是对--hidden-import
文件夹中的每个文件使用jinxed.terminfo
。