2024-05-29 04:01:32 发布
网友
运行简单的.py或.pyw python文件会导致python.exe显示在任务管理器下。
python.exe
python myApp.py python myApp.pyw
但是,当我们尝试在不使用控制台的情况下运行它时,脚本似乎不会运行,任务管理器下也不会出现python.exe或pythonw.exe
pythonw.exe
pythonw myApp.pyw pythonw myApp.py
我们如何解决这个问题?系统正在运行Python2.7.8x64。
tl;dr
要排除故障,请在调用时使用输出重定向:
pythonw myApp.py 1>stdout.txt 2>stderr.txt
这将捕获来自print()、文件stdout.txt中的stdout输出和来自PowerShell的文件stderr.txt中的stderr输出(例如来自未处理的异常);使用cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt. 注意,重定向stdout的行为实际上可能会使脚本再次工作,如果它失败的唯一原因是使用了pythonw(在Python 2.x中-见下文)。警告:当直接调用*.pyw脚本时,这种输出重定向技术似乎不起作用(而不是通过将脚本文件路径传递给pythonw.exe)。如果您知道原因和/或它对您有用,请告诉我。
print()
stdout.txt
stderr.txt
cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt
pythonw
*.pyw
将以下内容放在要用pythonw.exe运行的任何Python 2.x或3.x脚本的顶部:
import sys, os if sys.executable.endswith("pythonw.exe"): sys.stdout = open(os.devnull, "w"); sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")
这可确保在使用pythonw.exe运行脚本时执行以下操作:
sys.stdout()
%TEMP%\stderr-<scriptFileName>
%TEMP%
换言之:使用上述代码,当使用pythonw.exe调用脚本时,在脚本无提示失败后检查文件%TEMP%\stderr-<scriptFileName>。
要得到解释,请继续阅读。
在Windows上,pythonw.exe用于在所有脚本上启动GUI/no UI,这意味着 标准输入和输出流-sys.stdin、sys.stdout、sys.stderr不可用。
sys.stdin
sys.stdout
sys.stderr
这有两个讨厌的副作用:
上述代码通过以下方法解决了这些问题:
将stdout输出发送到空设备,有效地忽略任何试图输出到sys.stdout的尝试-无论是显式的还是隐式的通过print()。
将所有stderr输出发送到临时文件。
Python2.x和Python3.x之间的区别:
当使用pythonw.exe、sys.stdin、sys.stdout和sys.stderr运行脚本时:
IOError: [Errno 9] Bad file descriptor
-u
None
sys.stdout.write()
sys.stderr.write()
有关更多背景信息,请参见here。
我在自己的脚本上遇到了同样的问题,发现当添加Ross的答案的输出时,脚本实际上会运行。
出于某种原因,重定向输出似乎解决了问题。由于我对将输出写入磁盘不感兴趣,所以我改为使用以下命令将其写入/dev/null(或等效于平台的命令):
/dev/null
if ( sys.platform == 'win32' and sys.executable.split( '\\' )[-1] == 'pythonw.exe'): sys.stdout = open(os.devnull, 'w') sys.stderr = open(os.devnull, 'w')
if语句确保只在脚本从pythonw.exe启动时发生。我不确定它是否相关,但在其他导入(包括import logging)之前执行此操作很重要。
import logging
尝试将import sys; sys.stderr = open("errlog.txt", "w")行添加到myApp.py的开头。然后在errlog.txt中查找回溯或任何其他错误消息。
import sys; sys.stderr = open("errlog.txt", "w")
myApp.py
errlog.txt
tl;dr
要排除故障,请在调用时使用输出重定向:
这将捕获来自
print()
、文件stdout.txt
中的stdout输出和来自PowerShell的文件stderr.txt
中的stderr输出(例如来自未处理的异常);使用cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt
.注意,重定向stdout的行为实际上可能会使脚本再次工作,如果它失败的唯一原因是使用了
pythonw
(在Python 2.x中-见下文)。警告:当直接调用
*.pyw
脚本时,这种输出重定向技术似乎不起作用(而不是通过将脚本文件路径传递给pythonw.exe
)。如果您知道原因和/或它对您有用,请告诉我。将以下内容放在要用
pythonw.exe
运行的任何Python 2.x或3.x脚本的顶部:这可确保在使用
pythonw.exe
运行脚本时执行以下操作:print()
对sys.stdout()
的调用和显式调用被有效地忽略(不是操作)。%TEMP%\stderr-<scriptFileName>
;%TEMP%
是一个标准的Windows环境变量,它指向当前用户文件夹中的临时文件。换言之:使用上述代码,当使用
pythonw.exe
调用脚本时,在脚本无提示失败后检查文件%TEMP%\stderr-<scriptFileName>
。要得到解释,请继续阅读。
在Windows上,
pythonw.exe
用于在所有脚本上启动GUI/no UI,这意味着 标准输入和输出流-sys.stdin
、sys.stdout
、sys.stderr
不可用。这有两个讨厌的副作用:
print()
-默认情况下目标是sys.stdout
-会导致Python 2.x中出现异常。print()
触发的异常-导致脚本自动中止。sys.stderr
,这在本场景中是不可用的。上述代码通过以下方法解决了这些问题:
将stdout输出发送到空设备,有效地忽略任何试图输出到
sys.stdout
的尝试-无论是显式的还是隐式的通过print()
。将所有stderr输出发送到临时文件。
Python2.x和Python3.x之间的区别:
当使用
pythonw.exe
、sys.stdin
、sys.stdout
和sys.stderr
运行脚本时:sys.stdout
或sys.stderr
时,最终的结果是以下异常:IOError: [Errno 9] Bad file descriptor
-u
(对于无缓冲输出)调用pythonw.exe
立即触发它。print()
盲目尝试sys.stdout
(默认情况下),因此迟早会引发此异常。None
sys.stdout
是None
时,3.xprint()
函数执行no op(不执行任何操作)作为补充,这样print()
语句在默认情况下就可以安全地使用-当与pythonw.exe
一起运行时,它们将被忽略sys.stdout.write()
和sys.stderr.write()
仍然会导致异常。有关更多背景信息,请参见here。
我在自己的脚本上遇到了同样的问题,发现当添加Ross的答案的输出时,脚本实际上会运行。
出于某种原因,重定向输出似乎解决了问题。由于我对将输出写入磁盘不感兴趣,所以我改为使用以下命令将其写入
/dev/null
(或等效于平台的命令):if语句确保只在脚本从
pythonw.exe
启动时发生。我不确定它是否相关,但在其他导入(包括import logging
)之前执行此操作很重要。尝试将
import sys; sys.stderr = open("errlog.txt", "w")
行添加到myApp.py
的开头。然后在errlog.txt
中查找回溯或任何其他错误消息。相关问题 更多 >
编程相关推荐