Python try/finally 与 sys.exc_info()
Python try/finally wtih sys.exc_info()
我正在尝试编写一个 python 作业,我将在所有其他作业中使用它来捕获作业开始时间,当程序成功完成或出现一些问题时,我捕获错误详细信息并将详细信息加载到 table.
job_status
def srt(jobname):
sts = 'running'
df_srt = select(f'''select /'{job_name}/' as job_name, /'{strt_time}/' as strt_time, /'{sts}/' as sts''')
df_srt.write.to_csv(/path_name)
def end(jobname):
df_end = select(f'''select /'{job_name}/' as job_name, /'{strt_time}/' as strt_time, /'{end_time}/', /'{log}/' as log, /'{sts}/' as sts ''')
df_end.write.to_csv(/path_name)
我正在使用作业的程序
from job_status import *
def main_program:
try:
# some operation
print(1/0)
except:
pass
finally:
if sys.exc_info()[0] is not None:
status = 'Failed'
log = concat(sys.exc_info()[0],' , ', sys.exc_info()[1], ' , ', sys.exc_info()[2])
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, strt_time=start_time, end_time=end_time, sts=sts, log=log)
else:
sts = 'Success'
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, start_time=start_time, end_time=end_time, status=status)
每当出现问题时,我都会尝试捕获错误详细信息。但无论错误的性质如何,sys.exc_info()[0] 都会进入成功路径。任何想法,我如何实现这个?
sys.exc_info()
包含当前正在处理的异常 的信息。来自 docs(强调我的):
This function returns a tuple of three values that give information about the exception that is currently being handled. [...] If the current stack frame is not handling an exception, the information is taken from the calling stack frame, or its caller, and so on until a stack frame is found that is handling an exception. Here, “handling an exception” is defined as “executing an except clause.” For any stack frame, only information about the exception being currently handled is accessible. If no exception is being handled anywhere on the stack, a tuple containing three None
values is returned.
在 finally
子句中,您已经过去了 处理异常的时间点。因此,您需要从 except
子句的 inside 中保存有关异常的相关信息。例如:
exc_info = None
try:
# some operation
print(1/0)
except:
exc_info = sys.exc_info()
finally:
if exc_info is not None:
status = 'Failed'
# ...
else:
status = 'Success'
# ...
(注意:注释表明 OP 中的代码并非旨在捕获异常;相反,其目的只是记录成功或失败,并让原始异常传播。此处的代码已被修改以实现该目的。)
try
命令包括三种附加子句:except
、else
和finally
:
"except" [expression ["as" identifier]]
如果提供表达式,则在抛出与表达式匹配的异常时执行该子句。如果未提供表达式,则在抛出任何异常时执行该子句。
else
如果没有抛出异常,则执行该子句。
finally
该子句在 try
块的末尾执行,在任何匹配的 except
或 else
子句之后。
(具体语法见[注1],详情见Python docs)
sys.exc_info
可用于 在 except
子句中 (或在执行 except
子句期间调用的函数中)提取有关异常的信息。一旦 except
子句结束,sys.exc_info
就不再是 returns 有用的信息。由于 finally
子句在 except
子句完成后执行,因此您的代码就是这种情况。
但是你试图用 if exc_info is not None:
做的正是 try
语句的 else
子句所做的。因此,您可以使用 else
子句更简单地编写代码。我做了一些重构,以便能够将通用代码放在 finally
子句中。
为了传播异常,有必要用 raise
语句结束 except
子句,而不用表达式。这将导致异常继续“就像它是由 try
块引发的一样”。但是,finally
子句仍然在传播之前执行。
def main_program:
start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
# some operation
print(1/0)
except:
status = 'Failed'
log = concat(sys.exc_info()[0],' , ', sys.exc_info()[1], ' , ', sys.exc_info()[2])
raise
else:
status = 'Success'
log = None
finally:
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, start_time=start_time, end_time=end_time, sts=sts, log=log)
备注:
try
语句的精确语法表明您必须至少有一个 except
子句或一个 finally
子句,并且您只能有一个 else
子句,如果你有 except
子句。从文档:
try_stmt ::= try1_stmt | try2_stmt
try1_stmt ::= "try" ":" suite
("except" [expression ["as" identifier]] ":" suite)+
["else" ":" suite]
["finally" ":" suite]
try2_stmt ::= "try" ":" suite
"finally" ":" suite
- 我不知道
concat
应该在这里做什么,所以我就保持原样。它不能是简单的字符串连接,因为 sys.exc_info
返回的元组的组成部分不是字符串,如果那是您正在寻找的内容,', '.join(map(str, exc_info()))
就可以。如果它是一些可以很好地格式化 sys.exc_info
返回的对象的函数,那么您可以考虑只将 sys.exc_info
. 返回的对象传递给它
我正在尝试编写一个 python 作业,我将在所有其他作业中使用它来捕获作业开始时间,当程序成功完成或出现一些问题时,我捕获错误详细信息并将详细信息加载到 table.
job_status
def srt(jobname):
sts = 'running'
df_srt = select(f'''select /'{job_name}/' as job_name, /'{strt_time}/' as strt_time, /'{sts}/' as sts''')
df_srt.write.to_csv(/path_name)
def end(jobname):
df_end = select(f'''select /'{job_name}/' as job_name, /'{strt_time}/' as strt_time, /'{end_time}/', /'{log}/' as log, /'{sts}/' as sts ''')
df_end.write.to_csv(/path_name)
我正在使用作业的程序
from job_status import *
def main_program:
try:
# some operation
print(1/0)
except:
pass
finally:
if sys.exc_info()[0] is not None:
status = 'Failed'
log = concat(sys.exc_info()[0],' , ', sys.exc_info()[1], ' , ', sys.exc_info()[2])
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, strt_time=start_time, end_time=end_time, sts=sts, log=log)
else:
sts = 'Success'
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, start_time=start_time, end_time=end_time, status=status)
每当出现问题时,我都会尝试捕获错误详细信息。但无论错误的性质如何,sys.exc_info()[0] 都会进入成功路径。任何想法,我如何实现这个?
sys.exc_info()
包含当前正在处理的异常 的信息。来自 docs(强调我的):
This function returns a tuple of three values that give information about the exception that is currently being handled. [...] If the current stack frame is not handling an exception, the information is taken from the calling stack frame, or its caller, and so on until a stack frame is found that is handling an exception. Here, “handling an exception” is defined as “executing an except clause.” For any stack frame, only information about the exception being currently handled is accessible. If no exception is being handled anywhere on the stack, a tuple containing three
None
values is returned.
在 finally
子句中,您已经过去了 处理异常的时间点。因此,您需要从 except
子句的 inside 中保存有关异常的相关信息。例如:
exc_info = None
try:
# some operation
print(1/0)
except:
exc_info = sys.exc_info()
finally:
if exc_info is not None:
status = 'Failed'
# ...
else:
status = 'Success'
# ...
(注意:注释表明 OP 中的代码并非旨在捕获异常;相反,其目的只是记录成功或失败,并让原始异常传播。此处的代码已被修改以实现该目的。)
try
命令包括三种附加子句:except
、else
和finally
:
"except" [expression ["as" identifier]]
如果提供表达式,则在抛出与表达式匹配的异常时执行该子句。如果未提供表达式,则在抛出任何异常时执行该子句。
else
如果没有抛出异常,则执行该子句。
finally
该子句在
try
块的末尾执行,在任何匹配的except
或else
子句之后。
(具体语法见[注1],详情见Python docs)
sys.exc_info
可用于 在 except
子句中 (或在执行 except
子句期间调用的函数中)提取有关异常的信息。一旦 except
子句结束,sys.exc_info
就不再是 returns 有用的信息。由于 finally
子句在 except
子句完成后执行,因此您的代码就是这种情况。
但是你试图用 if exc_info is not None:
做的正是 try
语句的 else
子句所做的。因此,您可以使用 else
子句更简单地编写代码。我做了一些重构,以便能够将通用代码放在 finally
子句中。
为了传播异常,有必要用 raise
语句结束 except
子句,而不用表达式。这将导致异常继续“就像它是由 try
块引发的一样”。但是,finally
子句仍然在传播之前执行。
def main_program:
start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
try:
# some operation
print(1/0)
except:
status = 'Failed'
log = concat(sys.exc_info()[0],' , ', sys.exc_info()[1], ' , ', sys.exc_info()[2])
raise
else:
status = 'Success'
log = None
finally:
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
end(job_name=__name__, start_time=start_time, end_time=end_time, sts=sts, log=log)
备注:
try
语句的精确语法表明您必须至少有一个except
子句或一个finally
子句,并且您只能有一个else
子句,如果你有except
子句。从文档:try_stmt ::= try1_stmt | try2_stmt try1_stmt ::= "try" ":" suite ("except" [expression ["as" identifier]] ":" suite)+ ["else" ":" suite] ["finally" ":" suite] try2_stmt ::= "try" ":" suite "finally" ":" suite
- 我不知道
concat
应该在这里做什么,所以我就保持原样。它不能是简单的字符串连接,因为sys.exc_info
返回的元组的组成部分不是字符串,如果那是您正在寻找的内容,', '.join(map(str, exc_info()))
就可以。如果它是一些可以很好地格式化sys.exc_info
返回的对象的函数,那么您可以考虑只将sys.exc_info
. 返回的对象传递给它