在Python 3.4中调用子进程并处理无效命令的错误?
我正在尝试在Python 3.4中执行一个外部程序。当我的“命令”写错了时,程序就会崩溃。有什么办法可以优雅地处理这些错误,并让程序恢复过来吗?
# Call a system process
try:
pipe = subprocess.Popen(command,
stdout=subprocess.PIPE)
except (OSError,
subprocess.CalledProcessError) as error:
print("Failed to execute command")
print(command)
print("Error: " + error.output)
while True:
output = pipe.stdout.readline()
if not output:
print("Finished...")
break
output = output.decode()
output = output.strip("\r")
output = output.strip("\n")
print(output)
当我调用一个无效的命令时,程序会崩溃,像这样:
C:\SDKs\Python34\python.exe C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\main.py
Traceback (most recent call last):
Executing: windeployqt.exe C:\Users\user\Documents\GitHub\SpaCentralSoftBin\GUIController.exe
File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 81, in execute_windeployqt
Failed to execute command
stdout=subprocess.PIPE)
windeployqt.exe C:\Users\user\Documents\GitHub\SpaCentralSoftBin\GUIController.exe
File "C:\SDKs\Python34\lib\subprocess.py", line 858, in __init__
restore_signals, start_new_session)
File "C:\SDKs\Python34\lib\subprocess.py", line 1111, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 159, in on_buttonBox_clicked
self.execute_windeployqt()
File "C:\Users\user\Documents\GitHub\PyQtApps\QtDeploy\src\forms\maindialog.py", line 86, in execute_windeployqt
print("Error: " + error.output)
AttributeError: 'FileNotFoundError' object has no attribute 'output'
2 个回答
1
FileNotFoundError' object has no attribute 'output'
使用
print("Error: " + error)
FileNotFoundErrr
有一些可能会对你有用的属性:
args
characters_written
errno
filename
filename2
2
更大的问题是,打印错误信息并不能真正“处理”错误,虽然很多人认为这样做是有效的。
如果你想记录一个错误信息,那就记录吧,然后退出你的程序。实际上,能够处理错误的情况很少,比如说如果一个配置文件无法读取,你可以尝试读取一个全局的配置文件,或者把KeyboardInterrupt传递给一个主循环,这个主循环在读取命令。
在你的例子中,如果你在except块里没有出错,output = pipe.stdout...
会导致:
NameError: name 'pipe' is not defined
即使你捕获了这个错误,仍然没有什么有效的方法来恢复你的代码所期望的状态。而且,你还会把你得到的错误追踪信息移动到一个没有错误的地方。
在这种情况下,一个好的做法是
except SomeError:
log what you want
raise
这里一个空的raise
会重新抛出最后一个异常,这样会向上传播,形成一个完整的错误追踪信息,这样你就能更清楚地知道错误出在哪里。如果你不这样做,你就会丢失有用的信息。