是存在的,我們可以捕捉和記錄一般Python腳本的斷言語句,儘管斷言在Python2.7任何方式是真的還是假 假設在代碼中,我斷言下面一行:如何捕捉python腳本斷言
assert len(lst) ==4
所以有什麼方法可以記錄什麼語句傳遞,在哪一行,它是真或假。我不想使用包裝函數,尋找python內置的東西。
注:我想要實現的是,假設我有遺留代碼有1000個斷言語句,而不更改代碼,我應該能夠記錄哪個斷言語句被執行以及輸出是什麼,是否可以實現python 2.7。
是存在的,我們可以捕捉和記錄一般Python腳本的斷言語句,儘管斷言在Python2.7任何方式是真的還是假 假設在代碼中,我斷言下面一行:如何捕捉python腳本斷言
assert len(lst) ==4
所以有什麼方法可以記錄什麼語句傳遞,在哪一行,它是真或假。我不想使用包裝函數,尋找python內置的東西。
注:我想要實現的是,假設我有遺留代碼有1000個斷言語句,而不更改代碼,我應該能夠記錄哪個斷言語句被執行以及輸出是什麼,是否可以實現python 2.7。
是的,你可以自定義一個excepthook
記錄一些額外的信息:
import sys
import logging
def excepthook(*args):
logging.getLogger().error('Uncaught exception:', exc_info=args)
sys.excepthook = excepthook
assert 1==2
編輯:哎呀我忘了你想登錄,即使這是真的:)哦,我會離開這個一點點如果它通知你或其他人...
這是我可以實現closet,因爲似乎不可能在Python2.7。我創建了一個包裝函數。
import inspect
def assertit(condition,message):
# The caller method
(frame, filename, line_number,function_name, lines, index) = inspect.getouterframes(inspect.currentframe())[1]
detailed_message=" => {message} [ {filename} : {line_number}]".format(message=message,line_number=line_number,
filename=filename)
if condition:
print "True %s"%detailed_message
return
raise AssertionError("False: %s"%detailed_message)
assertit(1==1,"Check if 1 equal 1")
assertit(1==2,"Check if 1 equal 2")
### HERE IS THE OUTPUT
True => Check if 1 equal 1 [ test_cases.py : 20]
Traceback (most recent call last):
File "test_cases.py", line 21, in <module>
assertit(1==2,"Check if 1 equal 2")
File "test_cases.py", line 19, in assertit
raise AssertionError("False: %s"%detailed_message)
AssertionError: False: => Check if 1 equal 2 [ test_cases.py : 21]
這是一個概念驗證。所以請downvote,否則我會刪除它... 這個想法是在執行時用print
聲明替換assert
聲明。
import ast
import inspect
from your_module import main
def my_assert(test_result, msg):
assert test_result, msg
# if test_result is True, just print the msg
return "assert: {}, {}".format(test_result, msg)
class Transformer(ast.NodeTransformer):
def visit_Assert(self, node):
f = ast.Name(id='my_assert', ctx=ast.Load())
c = ast.Call(func=f, args=[node.test, node.msg], keywords=[])
p = ast.Print(values=[c], nl=True)
# set line#, column offset same as the original assert statement
f.lineno = c.lineno = p.lineno = node.lineno
f.col_offset =c.col_offset = p.col_offset = node.col_offset
return p
def replace_assert_with_print(func):
source = inspect.getsource(func)
ast_tree = ast.parse(source)
Transformer().visit(ast_tree)
return compile(ast_tree, filename="<ast>", mode="exec")
if __name__ == '__main__':
exec(replace_assert_with_print(main))
main(4)
這裏是your_module.py
def main(x):
assert x == 4, "hey {} is not 4".format(x)
return x
謝謝看看我的解決方案,似乎我們正在做同樣的事情,我也傳遞一條消息,並從檢查獲取被調用方法的模塊和行號。 – sudhanshu
哦....我想我可以用'try-except'包裝'assert'語句,而不是用print語句替換 –
@sundhanshu我試圖滿足要求:不更改代碼:-) –
對不起 - 你什麼意思「任何方式通過什麼語句可以登錄」?看起來你想要記錄某些東西而不是_assert_它。 – mgilson
你想登錄異常嗎? –
不,我想知道是否有可能,不知何故解釋器在執行過程中看到它是否有斷言聲明,它應該告訴它執行的是哪一行,是真還是假。還有什麼是斷言聲明。 – sudhanshu