更灵活的警告模块。
项目描述
warn
更好的警告。
查看完整 文档。
Python标准 警告模块 非常好,但我认为它被低估了;尽管它缺少一些功能;特别是它只允许根据触发/调用弃用函数的代码进行过滤,但没有根据发出警告的模块进行过滤的能力。
这是尝试解决这个问题。
略
明确优于暗示
from warn import patch patch() # use the warning module as usual
尽管现在 warnings.filterwarning 函数已经增加了 emodule 关键字参数,可以根据发出警告的模块进行过滤;例如
import warnings warnings.filter('default', category=DeprecationWarnings, emodule='matplotlib\.pyplot.*')
现在默认显示来自 matplotlib.pyplot 和其子模块的所有警告,无论您是否直接触发它们,通过pandas,seaborn,您自己的代码等。
警告发出者,警告调用者。
Python警告是一段相对简单但非常强大的代码,一旦您学会了如何使用它,它在正确手中就非常强大。
它允许您事后确定是否希望特定的代码块触发异常,向用户显示消息或简单地什么也不做。
很难用一段简单的代码展示警告的全部威力,但在大型代码库中,一旦您开始使用多层依赖,节约地使用警告,尤其是 DeprecationWarning,可以产生很大的影响。
调用者,与发出者
让我们先澄清一些术语,以区分警告“调用者”和警告“发出者”
# file emitter.py
def public_api(param1, deprecated_parameter=None)::
if deprecated_parameter:
return _deprecated_function(param1, deprecated_parameter):
else:
return normal_buisnell_logic(param1)
def _deprecated_function(param1, deprecated_parameter):
import warningsA
# warning emitted here
warnings.warn('using `deprecated_parameter` is deprecated ',
DeprecationWarning,
stacklevel=3)
# file caller.py
from emitter import public_api
public_api(1, True) # warning triggered here.
您现在可以做一些像这样的事情
from warn import path
patch()
import warnings
warnings.filter('default', category=DeprecationWarnings, emodule='emitter.*')
import emitter
emitter.bar() # will log the warning !
请将测试套件中的此内容更改为“错误”,并通过所有依赖项进行过滤!
Python内置模块允许您通过调用者过滤警告(假设发射者已正确设置stacklevel选项,这并不总是明显)。当您正在开发调用者时,这非常有用;但是当您正在开发发射者时,作用就不大了。
调用者实际上可能有多个底层库可以触发警告,或者开发者可能只关心发射者警告的一部分。
许多库通过子类化Warning来绕过这个限制;两个例子是Matplotlib和sympy,以便有选择地启用它们。然而,这仅提供了一种粗略的过滤警告方式,并且需要知道警告在哪里定义,才能导入和过滤它们。
由于Python默认会过滤掉弃用警告,这也迫使您要么继承UserWarning(matplotlib的选择),这消除了Python提供的DeprecationWarning的语义意义,要么在导入时在警告过滤模块中注入自定义过滤器(Sympy的选择),这可能导致意外行为。
Python 2上的可用性
我不知道它是否在Python 2上工作;我实在没有时间去调查;我并不特别关心;但如果需要,您可以随时发送一个PR以添加支持,我很乐意将其合并。
限制
这不能在以下包上工作
在调用patch()之前获取并保留对warnings.warn的引用;也就是说,形式如下:from warnings import warn
不能在C扩展(即不会在numpy上过滤)上工作;上述两种情况都可通过汇编修补来实现,但我对此不太舒服。
糟糕的部分
由于警告过滤器必须是具有特定类型的5个元组,因此它通过在过滤器列表中放入虚拟实例,并使用这些实例作为代理查找真实过滤器键的键来实现。所以最坏的情况是,您用这个模块插入的过滤器将没有任何效果。但是,如果您使用这个,尤其是如果您的代码库触发了大量警告,您将承担性能损失。
获取上游
我非常希望能够得到反馈,并有一个更好的API来处理CPython级别的警告,以便提供自定义过滤器,和自定义过滤器函数。
轶事
良好的弃用警告。
一个好的警告,特别是弃用警告,非常有帮助,并且可以改变API的采用率。以下是一个虚构的例子
>>> import warnings
>>> warnings.simplefilter('default')
>>> from quezetraste import frobulate, constribule
>>> frobulate('HI', 3)
DeprecationWarning: The 'frobulate' function is deprecated.
>>> contribule('Hi', 3)
DeprecationWarning: The 'constribule(message, recipient_id)' function of the
'quezetraste' package is deprecated since version 7.3. It
haz been replaced by 'Recipient(id).send(message)' which
was available since 7.2. See http://url.to/documentation/#1337
将弃用警告转换为测试套件中的错误!
至少使它们可见;最好是在修复了一个弃用警告后,将这个特定的警告转换为错误,以防止其再次出现。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
warn-0.1.0-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 12d7b9728cea836a5835a3014ee5dca6b881928aa3c6825c1c7aff2ad1470181 |
|
MD5 | b2a4edddf402c8c0bebb0146415b3294 |
|
BLAKE2b-256 | 00738f83635cecd46458d6fbffc6e6a3906babd0c79ab96fa72624bc0580c9a0 |