下面的代码中需要修改什么特定的语法,才能使损坏的脚本停止调用它的程序?
问题:
一个面向对象的Python 3程序需要运行外部脚本。问题是,当程序调用中断的脚本时,Python程序只是继续运行,而不是停止并显示错误消息。
脚本是由我们无法控制的第三方提供的,因此当调用脚本中断时,面向对象的Python 3程序需要进行错误处理,我们无法控制调用脚本的内容。
重现问题的步骤:
1.创建两个目录,并将以下4个文件放在这两个目录中。一个目录名为MyApp,另一个目录名为AnotherDir。文件结构应如下所示:
AnotherDir\scripts\brokenScript.py
MyApp\app\main.py
MyApp\app\second_level.py
MyApp\app\third_level.py
1.将命令行导航到AnotherDir和MyApp的父目录
1.运行以下命令重现问题:
python MyApp\app\main.py
我们正在Windows上开发这个,但它的目的是与操作系统无关。
问题结果:
问题是结果看起来像:
About to run a broken script that should break on error.
command is: python C:\path\to\AnotherDir\scripts\brokenScript.py
shell Inside broken script. The script should break on the next line.
----------------------------------------------------------------------------
FAILED TO THROW ERROR. Done running the broken script, but it returned without breaking this calling program. This print command should never run if the script breaks. Instead, a graceful error message should terminate the program.
确认结果:
brokenScript.py脚本的非零退出代码应该会导致调用程序停止而不是继续运行。
重现问题的代码:
100%重现此错误的最低限度代码如下:AnotherDir\scripts\brokenScript.py
包含:
import sys
print("Inside broken script. The script should break on the next line. ")
sys.exit(1)
MyApp\main.py
包含:
from second_level import second_level
import sys
def runCommands():
wfsys = second_level()
wfsys.offFoundation()
print("--------------------------------------")
sys.exit(0)
runCommands()
MyApp\second_level.py
包含:
from third_level import third_level
class second_level:
def __init__(self):
pass
def offFoundation(self):
tl = third_level()
print("About to run a broken script that should break on error.")
callScript = "\\AnotherDir\\scripts\\brokenScript.py"
tl.runScript(callScript)
print("----------------------------------------------------------------------------")
print("FAILED TO THROW ERROR. Done running the broken script, but it returned without breaking this calling program. This print command should never run if the script breaks. Instead, a graceful error message should terminate the program.")
MyApp\third_level.py
包含:
import subprocess
import re
import sys
import os
import platform
class third_level:
def __init__(self):
pass
ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
def runShellCommand(self, commandToRun):
proc = subprocess.Popen( commandToRun,cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
while True:
line = proc.stdout.readline()
if line:
thetext=line.decode('utf-8').rstrip('\r|\n')
decodedline=self.ansi_escape.sub('', thetext)
logString = decodedline
print("shell", logString)
else:
break
def runScript(self, relativePathToScript):
userCallingDir = str(os.path.abspath("."))+'\\'
userCallingDir = self.formatPathForOS(userCallingDir)
fullyQualifiedPathToScript = userCallingDir+relativePathToScript
fullyQualifiedPathToScript = self.formatPathForOS(fullyQualifiedPathToScript)
if os.path.isfile(fullyQualifiedPathToScript):
commandToRun = "python "+fullyQualifiedPathToScript
print("command is: ",commandToRun)
self.runShellCommand(commandToRun)
else:
logString = "ERROR: "+fullyQualifiedPathToScript+" is not a valid path. "
print('shell', logString)
sys.exit(1)
def formatPathForOS(self, input):
if platform.system() == "Windows":
input = input.replace('/','\\')
else:
input = input.replace('\\','/')
input = input.replace('//','/')
if input.endswith('/n'):
input = input[:-2] + '\n'
return input
1条答案
按热度按时间j7dteeu81#
对于OP中给出的代码,解决方案是添加以下三行:
添加了这三行的函数的完整代码如下所示:
OP中的其他一切都可以保持不变,整个程序将按预期工作。