我建立使用Python和PySide一个相当复杂的应用程序。 最后发布之日起已接近尾声,所以我要构建这个应用程序作为一个exe。
但是,我有我的手一个奇怪的问题。 我用PyInstaller(使用第2版的方式)在过去从来没有这样发生在我身上。
基本上,当我建立与应用--console
标志,它工作正常-但它打开控制台窗口。 当我建立与窗口标志(应用-w
),这是行不通的罚款。 它开始和一切,但也有这些奇怪的故障。 例如,加载一个文本文件,往往引发BadFileDescriptor
错误(这并不在控制台模式下发生),并执行特定任务后,该应用程序崩溃。 更糟糕的是,该任务是一个循环,它执行罚款的第一次,但它再次开始工作时,它崩溃。
当我看着转储文件大约有内存访问冲突QtGui4.dll文件的一些错误。 同样,这并不在控制台模式下发生的。
有人有主意吗?
的BadFileDescriptor
误差和因此存储器访问冲突由以下事实引起的stdout
的在窗口模式下的应用程序的大小是固定的缓冲区。 所以,如果你正在写到stdout
,无论是与print
或sys.stdout
直接,一段时间后,你会看到这些错误。
你可以解决这个问题:
- 删除/注释掉的著作
stdout
- 使用
logging
,而不是打印到标准输出 - 重定向
stdout
,在您的应用程序执行的开始。 这是一个需要更少的代码的解决方案改变,即使我想移动的调试语句logging
将是更好的选择。
要重定向stdout
,你可以使用这样的代码:
import sys
import tempfile
sys.stdout = tempfile.TemporaryFile()
sys.stderr = tempfile.TemporaryFile()
就在执行程序。 您还可以使用一些自定义的对象把输出“日志”文件或什么,重要的是输出不应该充满固定大小的缓冲区。
例如,你可以做这样的事情,以便能够利用的logging
模块,而无需改变太多的代码:
import sys
import logging
debug_logger = logging.getLogger('debug')
debug_logger.write = debug_logger.debug #consider all prints as debug information
debug_logger.flush = lambda: None # this may be called when printing
#debug_logger.setLevel(logging.DEBUG) #activate debug logger output
sys.stdout = debug_logger
这种方法的缺点是print
执行多次调用stdout.write
每行:
>>> print 'test'
DEBUG:debug:test
DEBUG:debug:
如果你想你大概能避免这种行为写一个真正的write
调用函数the_logger.debug
只能用“实线”。
反正我觉得这些种解决方案应该只是暂时的,只有在移植之前,用来print
s到呼叫logging.debug
。
(显然,记录仪应写入文件,而不是stdout
,以避免错误。)
文章来源: PyInstaller packaged application works fine in Console mode, crashes in Window mode