警告通常用于提醒某人可能遇到的情况,但这种情况并不需要始终如此。
同样,Python 中的警告用于提醒程序员注意并非异常的情况。它们用于警告程序员出现的问题不会中断代码流,但可能会导致意外的代码行为。
用户在编码时可能会遇到许多警告变体。虽然它们有助于让我们知道在某些情况下可能会发生什么,但如果它们频繁发生,它们可能会令人恼火。
在本教程中,我们将了解警告、它们的变体以及如何禁用此类警告。
在我们进一步讨论之前,请访问本文以了解 Python 模块。
什么是警告?
如上所述,警告用于警告程序员有关不会终止程序或引发任何异常但有时会导致代码出现意外行为的情况。一种常见的情况是,当用户尝试使用不再使用或过时的模块或包时,会打印警告消息。警告与异常不同。虽然在出现异常的情况下无法进一步执行代码,但在出现警告的情况下,代码会照常运行。
Python 中有一个名为 的专用模块warnings
,可以参考它来了解警告及其一般功能。
警告和错误之间的区别
虽然警告和错误都用于让程序员知道他们的代码存在问题,但它们之间存在显着差异。
错误是至关重要的。当代码出现问题必须更正才能正常运行时,就会发生错误。当发生错误时,IDE 会引发异常,应解决该异常才能使代码恢复执行。
警告并不重要。它们用于警告程序员可能发生的意外行为。它们不会干扰代码的执行。
让我们看一个错误和警告的示例。
下面给出了遇到错误的代码。
print ('Hello) |
正如您所看到的,上面的代码会生成语法错误,因为引号(”)没有正确关闭。
现在让我们看一个警告
#warning import warnings print ( 'Hello World' ) warnings.warn( "This is a warning" ) print ( 'HelloWorld2' ) |
如果不导入模块,我们就无法实现警告warnings
。我们试图在第三行打印一条简单的消息。
然后,我们使用该warnings
模块生成警告消息。
在下一行中,我们使用 print 函数打印另一条消息。
这样做是为了检查出现警告时代码执行流程是否被中断,
与错误不同的是,警告之后的代码仍然会执行。
警告类别
根据 Python 文档,大约有十种类型的警告。让我们一一介绍它们。
用户警告
这UserWarning
是该方法的默认类别warn()
。此警告用于通知用户代码稍后可能出现的问题。
下面给出了使用该warn()
方法生成 UserWarning 的一个示例。
import warnings print ( 'This is a message' ) warnings.warn( "This is a warning" ) print ( 'This is another message' ) |
输出如下所示。
折旧警告
折旧警告用于警告库或包的用户特定功能将被删除或将在新版本中更新。
库的开发人员使用折旧警告来提醒用户更新其现有的库版本以便能够使用新功能。
让我们看一个此类警告的示例。
1
2
3
4
|
import warnings import numpy as np a = np.bool_([ 0 , 1 , 0 , 1 ]) print (a) |
在上面的代码中,我们尝试打印与 0 和 1 相关的真值(True 和 False)。
我们使用np.bool_
numpy 库的构造函数来打印真值。
此代码应该显示一条警告消息,因为上面使用的构造函数不再实际使用或已被弃用。
这是完整的警告消息。
[False True False True]
/usr/local/lib/python3.9/dist-packages/ipykernel/ipkernel.py:283: DeprecationWarning: `should_run_async` 将来不会自动调用 `transform_cell`。请将结果传递给“transformed_cell”参数以及转换过程中发生的任何异常preprocessing_exc_tuple in IPython 7.17 and above.
and should_run_async(code)
我们看到此警告消息的原因是 Numpy 最近np.bool_
在从 1.20.0 开始的新版本中弃用了构造函数。我们可以查看版本的发行说明来了解已弃用的函数或构造函数。
语法警告
顾名思义,当用户尝试执行语法错误的代码时,将显示此警告。
1
2
3
|
import warnings r = 3 is 2 print (r) |
观察代码。该代码没有任何意义。如果我们想比较两个数字的值,我们应该使用运算==
符。is
但在上面的代码中,我们尝试使用用于根据对象的身份比较对象的运算符来检查两个数字是否相等。
除了这些警告之外,还有一些其他警告,例如RuntimeWarning
、 等,这可能取决于您正在使用的 Python 版本以及您执行代码的 IDE FutureWarning
。ImportWarning
如何创建自定义警告?
我们还可以在可能有问题的代码中显示我们自己的警告。我们可以借助模块方法根据代码打印我们选择的任何自定义警告warnings
。有几种方法可以做到这一点。
使用警告模块
在此示例中,我们将导入警告模块并使用其方法来显示自定义警告消息。
1
2
3
4
5
6
|
import warnings def func(z): if z < 0 : warnings.warn( "Oh! It is a negative number!" , UserWarning) return z + 11 func( - 4 ) |
如果我们尝试传递给func
函数的参数是负数,则此代码会生成警告。由于这是针对用户的,因此该警告属于 UserWarning 类别。
所以我们有一个名为 的函数func
,它接受一个名为 z 的参数。该函数是使用def
关键字创建的。
在这个函数内部,有一个 if 语句检查输入是否小于零。如果是这样,此代码会显示一条警告消息 – “哦!这是一个负数!”。
return z+11
用于计算我们传递给函数的参数和数字 11 的总和。
我们还尝试func
通过一些参数来调用。我们传递的参数是 -4,它是负数,因此代码应该显示一条警告消息。
创建自定义警告类
在此示例中,我们将为警告定义一个自定义类,并在警告消息中调用它。
1
2
3
4
5
6
7
8
|
import warnings class warn1(Warning): pass def func(y): if y < 0 : warnings.warn( "Oops! A negative number!" , warn1, stacklevel = 2 ) return y + 1 func( - 10 ) |
在上面的代码中,我们在第一行导入了警告模块。接下来,我们定义了一个名为的自定义类warn1
,它将警告作为参数。关键字 pass 用于防止类定义为空,因为类中没有语句。
我们使用了与上一个示例相同的函数。
在第六行中,我们将类名作为参数传递给方法warn
,stacklevel=2
这意味着仅显示警告而不显示警告源。
默认值为stacklevel
1,这意味着警告的来源也会显示在输出中。
这是堆栈级别 1 和 2 的比较。
如何禁用警告?
同意警告对于提醒用户潜在问题很有用,并且对于开发人员引入现有库或包的更改或更新也可能派上用场,您不能否认,如果您反复收到警告和最糟糕的情况,它肯定会变得烦人如果您一次又一次收到相同的警告。
有几种方法可以关闭代码中可能出现的警告。
使用过滤器警告()
我们可以使用filterwarnings
警告模块的方法来消除任何潜在的警告。让我们看一个示例,了解如何关闭前面示例中出现的折旧警告。
1
2
3
4
5
|
import warnings import numpy as np warnings.filterwarnings( "ignore" ) a = np.bool_([ 0 , 1 , 0 , 1 ]) print (a) |
上面代码中使用的构造np.bool_
函数应该会发出警告,因为它在较新版本的 numpy 库中已被弃用。因此,为了避免此警告,我们使用filterwarnings
警告模块中的 。
过滤器警告的语法如下所示。
filterwarnings(action, message, category, module, lineno)
在上面的代码中,我们使用的操作是ignore
从不打印警告消息。
使用filterwarnings()并指定类别
在前面的例子中,我们已经看到了filterwarnings()的语法。在此示例中,我们将指定不希望显示的警告的类别。
import warnings warnings.filterwarnings( 'ignore' ,category = SyntaxWarning) x = 41 if x is 41 : print ( "The number is 41" ) |
此代码必然会显示错误消息,因为is
运算符用于比较标识而不是值。但在这里,我们用它来比较值。因此它会生成语法警告。
我们将类别指定为 SyntaxWarning,以便忽略所有基于语法的警告。
使用闭嘴
Shutup 是一个第三方开源模块,用于消除警告。这是显示该模块用法的图像。
让我们看看是否可以通过闭嘴来消除警告。
import shutup; shutup.please() import warnings class warn1(Warning): pass def func(y): if y < 0 : warnings.warn( "Oops! A negative number!" , warn1, stacklevel = 2 ) return y + 1 func( - 10 ) |
此代码包含警告消息。因此,如果我们不使用 shutdown 模块,代码肯定会生成警告消息。
结论
警告是用于提醒用户有关他们正在使用的库或包中的任何潜在问题或任何更新的消息。与错误不同,它们不会终止代码。
用户在编码时可能会遇到多种警告。虽然它们有助于让我们知道在某些情况下可能会发生什么,但如果它们频繁发生,它们可能会令人恼火。
警告与错误不同。虽然存在错误的代码在错误解决之前不会执行,但如果发生警告,具有潜在警告的代码也不会终止。我们已经看到了警告和错误的示例,并观察了它们的功能。
根据情况,我们可以将警告分为多种类型。它们是 UserWarning、SyntaxWarnings、DepreciationWarning、FutureWarnings 等。
我们已经了解了如何生成自定义警告。warn
我们尝试使用警告模块的功能生成自定义警告。在下一个示例中,我们了解了如何使用自定义类来生成警告消息。