- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
简短版:
Is there way to achieve in Python the same effect achieved by Perl's
<a href="http://perldoc.perl.org/Carp.html" rel="noreferrer noopener nofollow">Carp::carp</a>
utility?
长版(对于那些不熟悉 Carp::carp
的人):
假设我们正在实现一些库 API 函数(即,它旨在被其他程序员在他们的代码中使用),比如 spam
,并假设 spam
包含一些代码来检查传递给它的参数的有效性。当然,如果检测到这些参数有任何问题,这段代码应该会引发异常。假设我们想让关联的错误消息和回溯对调试某些客户端代码的人尽可能有帮助。
理想情况下,由此引发的异常产生的回溯的最后一行应该查明“有问题的代码”,即客户端代码中的行 spam
使用无效参数调用。
不幸的是,至少在默认情况下,使用 Python 不会发生这种情况。相反,回溯的最后一行将引用库代码内部的某处,那里的异常实际上是 raise
。 'd,这对于这个特定追溯的目标受众来说是相当模糊的。
例子:
# spam.py (library code)
def spam(ham, eggs):
'''
Do something stupid with ham and eggs.
At least one of ham and eggs must be True.
'''
_validate_spam_args(ham, eggs)
return ham == eggs
def _validate_spam_args(ham, eggs):
if not (ham or eggs):
raise ValueError('if we had ham '
'we could have ham and eggs '
'(if we had eggs)')
# client.py (client code)
from spam import spam
x = spam(False, False)
当我们运行 client.py
,我们得到:
% python client.py
Traceback (most recent call last):
File "client.py", line 3, in <module>
x = spam(False, False)
File "/home/jones/spam.py", line 7, in spam
_validate_spam_args(ham, eggs)
File "/home/jones/spam.py", line 12, in _validate_spam_args
raise ValueError('if we had ham '
ValueError: if we had ham we could have ham and eggs (if we had eggs)
而我们想要的更接近于:
% python client.py
Traceback (most recent call last):
File "client.py", line 3, in <module>
x = spam(False, False)
ValueError: if we had ham we could have ham and eggs (if we had eggs)
...将违规代码 ( x = spam(False, False)
) 作为回溯的最后一行。
我们需要的是某种“从调用者的角度”报告错误的方法(这就是 Carp::carp
允许人们在 Perl 中做的事情)。
编辑:需要明确的是,这个问题不是关于 LBYL 与 EAFP,也不是关于先决条件或按契约(Contract)编程。如果我给了这个错误的印象,我很抱歉。这个问题是关于如何从调用堆栈的几层(一层、两层)开始产生回溯。
EDIT2:Python 的 traceback
模块显然是寻找 Perl 的 Carp::carp
的 Python 等价物的地方。 ,但在研究了一段时间后,我无法找到任何方法将它用于我想做的事情。 FWIW,Perl 的 Carp::carp
允许通过公开全局(因此动态范围)变量 $Carp::CarpLevel
来微调回溯的初始框架.可能 carp
的非 API 库函数-出,local
-ize 并在输入时增加此变量(例如 local $Carp::CarpLevel += 1;
)。我没有看到任何甚至远程像这个 Python 的 traceback
模块。所以,除非我遗漏了什么,否则任何使用 Python 的 traceback
的解决方案将不得不采取完全不同的策略......
最佳答案
这实际上只是一个约定问题,python 中的异常处理旨在大量使用(请求原谅而不是请求许可)。鉴于您在不同的语言空间中工作,您希望遵循这些约定——即/您确实想让开发人员知道异常站点在哪里。但是如果你真的需要这样做......
使用检查模块
inspect module将完成重建一个漂亮版本的 carp 所需的几乎所有工作,无需担心装饰器(见下文)。根据 comments in this answer ,可能这种方法会在 cpython 以外的 python 上中断
# revised carp.py
import sys
import inspect
def carp( msg ):
# grab the current call stack, and remove the stuff we don't want
stack = inspect.stack()
stack = stack[1:]
caller_func = stack[0][1]
caller_line = stack[0][2]
sys.stderr.write('%s at %s line %d\n' % (msg, caller_func, caller_line))
for idx, frame in enumerate(stack[1:]):
# The frame, one up from `frame`
upframe = stack[idx]
upframe_record = upframe[0]
upframe_func = upframe[3]
upframe_module = inspect.getmodule(upframe_record).__name__
# The stuff we need from the current frame
frame_file = frame[1]
frame_line = frame[2]
sys.stderr.write( '\t%s.%s ' % (upframe_module, upframe_func) )
sys.stderr.write( 'called at %s line %d\n' % (frame_file, frame_line) )
# Exit, circumventing (most) exception handling
sys.exit(1)
对于下面的例子:
1 import carp
2
3 def f():
4 carp.carp( 'carpmsg' )
5
6 def g():
7 f()
8
9 g()
产生输出:
msg at main.py line 4
__main__.f called at main.py line 7
__main__.g called at main.py line 9
使用回溯
这是最初提出的方法。
carp 的等价物也可以通过操作回溯对象用 python 编写,请参阅 traceback module 中的文档.这样做的主要挑战原来是注入(inject)异常和回溯打印代码。值得注意的是,本节中的代码非常脆弱。
# carp.py
import sys
import traceback
'''
carp.py - partial emulation of the concept of perls Carp::carp
'''
class CarpError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
def carpmain( fun ):
def impl():
try:
fun()
except CarpError as ex:
_, _, tb = sys.exc_info()
items = traceback.extract_tb(tb)[:-1]
filename, lineno, funcname, line = items[-1]
print '%s at %s line %d' % (ex.value, filename, lineno)
for item in items[1:]:
filename, lineno, funcname, line = item
print '\t%s called at %s line %d' % (funcname, filename, lineno)
return impl
def carp( value ):
raise CarpError( value )
可以使用以下基本过程调用:
import carp
def g():
carp.carp( 'pmsg' )
def f():
g()
@carp.carpmain
def main():
f()
main()
其输出为:
msg at foo.py line 4
main called at foo.py line 12
f called at foo.py line 7
g called at foo.py line 4
Perl 引用示例
为了完整起见,通过将结果与这个等效的 perl 示例进行比较来调试此答案中提出的两个解决方案:
1 use strict;
2 use warnings;
3 use Carp;
4
5 sub f {
6 Carp::carp("msg");
7 }
8
9 sub g {
10 f();
11 }
12
13 g();
输出结果:
msg at foo.pl line 6
main::f() called at foo.pl line 10
main::g() called at foo.pl line 13
关于python - 从调用者的角度发出警告(又名 Python 等同于 Perl 的鲤鱼)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8275745/
对于游戏,我正在尝试计算我正在看的位置与场景中另一个对象的位置之间的角度。我通过使用以下代码获得了角度: Vec3 out_sub; Math.Subtract(pEnt->vOrigin, pLoc
我还是 Firebase 的新手。有什么方法可以使用 Firebase 性能监控从控制台自动逐屏监控我们的 Web 应用程序?我检查了文档,它说我们需要在代码中添加一些跟踪来跟踪(如果我弄错了,请纠正
我正在使用 angular-material2 的复选框。目前复选框的默认颜色为紫色。 看起来他们已将复选框的默认颜色从“主要”更改为重音。 有没有办法在不覆盖 css 的情况下获得“主要”(绿色)颜
Angular-Material 中是否有任何分页指令可与 md-list 一起使用? 这些确实有效,但不是基于 Material 设计的。 https://github.com/brantwills
所以我有一个configmap config.json { "apiUrl": "http://application.cloudapp.net/", "test": "1232" } 称为“连续部署
我可以成功对图像进行阈值处理并找到图像的边缘。我正在努力尝试的是准确地提取黑色边缘的 Angular 。 我目前正在使用黑色边缘的极端点,并使用atan2函数计算 Angular ,但是由于混叠,根据
我需要一些帮助来计算点的角度: 我需要计算从点 (0,0) 到从图像中提取的点的角度。 1 将是 0*,2 大约是 40-44* 等。 我的问题是 atan2 显示的值不正确。atan2 的当前输出是
好的,所以我有一个运动场 512x512环绕,-32变成 512对于x和 y . 现在我需要计算两个实体之间的角度,我有以下代码作为一种解决方法,它在大多数时间都有效,但有时仍然会失败: Shoote
我有一个组件,它有一个子组件。子组件有一个按钮,可以打开一个 Material 对话框。 在对话框中,我们有表单、用户名和密码以及提交按钮。当我提交时,我正在调用后端 REST api。 这在子组件中
我一直在试图找到2之间的差异,但是要减去这个就没有运气了 The primary diff erence between the two representations is that a quate
我在 Angular Material Expansion 面板中遇到了这个问题。部分分页下拉菜单被切断。如何使下拉菜单与扩展面板的末端重叠?我尝试了 z-index 但没有成功。 Material
我正在创建一个PapperSoccer项目,但是在寻找运动/线条的方向时遇到了问题。我正在使用HoughLinesP来检测行,并且效果尽可能好。 我使用ROI,在其中寻找一行,然后相应地移动它。 到目
我正在寻找修改构建函数输出的方法 ng build --prod 想添加一些引导CSS文件到index.html的head部分,更改名称index.html => index.php等 怎么做? 最佳
如何获得两个单位向量之间的 x、y 和 z 旋转值?我不能使用点积,因为它只给我一个值。我想使用旋转矩阵在每个轴上旋转,对于那些我需要每个轴上的角度差。我尝试了仅两个组件的点积,但我有点困惑。有没有一
我必须计算图像中每条可检测线的斜率(或角度)。如果可能的话,甚至可以检测直线斜率的变化。我已经执行了 2D 傅立叶并且我知道每个区域的邻域平均角度(64x64px 的集合)。我什至尝试了 Hough
我正在使用Tiled map 编辑器创建简单的平铺 map 。在我的 map 中,我有几个矩形,如果我创建一个宽度为 50、高度为 10 的矩形并将其精确旋转 90°,则保存 map 并将其加载到我的
我计算了一个三角形的角度,但我不明白为什么我得到一些锐角的负角。例如: var sin = Math.Sin(4.45); var radians = Math.Atan(sin); var
我正在开发一个机器学习项目,其中使用 TensorFlow(和 DNNRegressor)。我想预测范围在 -pi 和 pi 之间的模算术值(角度)。当我尝试“正常方式”执行此操作时,模型不是很好,因
我有一个包含 40 个旋转图像的图像。 图像索引实际上从 0. 0-39 开始。 这是将 0-39 转换为度数的代码 int image_direction = 0; //Can be 0-39 in
在 PostGIS/PostgreSQL 中,是否有一个函数可以给出给定点所在的线串的线段的角度? 最佳答案 在 PostGIS 版本 1.5.3 上 ST_Azimuth()需要两点作为输入——据我
我是一名优秀的程序员,十分优秀!