在 Google Colab 中,当我运行以下命令时:
def f():
import warnings
warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
def g():
return f()
def h():
return g()
h() # or f() or g()
我在输出中收到 1 个警告:
<ipython-input-9-e09ca081f372>:6: DeprecationWarning: deprecated
return f()
当我跑步时:
f()
g()
h()
我只收到 2 个警告(我预计会收到 3 个警告,因为所有 3 个函数都被调用了):
<ipython-input-10-0d5243608655>:1: DeprecationWarning: deprecated
f()
<ipython-input-9-e09ca081f372>:6: DeprecationWarning: deprecated
return f()
现在,我在 Python 终端中尝试了相同的操作,但只收到了
f()
和 g()
的警告,而不是 h()
的警告
Python 3.11.1 (main, Feb 5 2023, 16:11:00) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
... import warnings
... warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
...
>>> def g():
... return f()
...
>>> def h():
... return g()
...
>>> f()
<stdin>:1: DeprecationWarning: deprecated
>>> g()
<stdin>:2: DeprecationWarning: deprecated
>>> h()
>>>
我想了解:
h()
时会在 colab 中看到警告,而当我在同一单元格中运行 f()
和 g()
时却看不到警告?为什么 h()
从不在 Python 终端中显示警告(我认为这是因为 stacklevel=2
)?在 colab 中运行警告代码与在 Terminal Python 中运行警告代码究竟有何不同?f()
时都显示警告消息?stacklevel
和 skip_file_prefixes
如何融入这一切?谢谢你:)
这是由于默认的警告过滤器,它只会打印每个位置第一次出现的警告。使用
stacklevel=2
时,警告位置是调用 f()
的位置,当您直接在笔记本中调用 <ipython-input-10-0d5243608655>:1
时,警告位置为 f()
;当您直接或间接调用 <ipython-input-9-e09ca081f372>:6
时,警告位置位于 g()
内部通过g()
。相同的逻辑适用于终端会话。请注意,如果您在 h()
之前调用 h()
,则警告将在 g()
之后打印:h()
笔记本和终端不一致大概就是这个问题:https://github.com/ipython/ipython/issues/11207
Python 3.12.3 (main, Apr 17 2024, 00:00:00) [GCC 13.2.1 20240316 (Red Hat 13.2.1-7)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
... import warnings
... warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
...
>>> def g():
... return f()
...
>>> def h():
... return g()
...
>>> f()
<stdin>:1: DeprecationWarning: deprecated
>>> h()
<stdin>:2: DeprecationWarning: deprecated
>>> g()
>>> g()
>>> h()
>>>
以编程方式更改警告过滤器。