在某些系统上使用 urllib
加载幻像模块时,似乎会出现一些意外行为。行为如下:
Python 3.5.2 (default, Aug 18 2017, 17:48:00)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> urllib.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'foo'
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'error', 'parse', 'request', 'response']
意外的行为是,仅在尝试访问错误属性并收到 AttributeError
后才加载其他名称。在另一个具有相同 python 解释器的系统上(Ubuntu 16.04 apt python3 ),这种情况不会发生:
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
>>> import urllib
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> urllib.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'foo'
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
我们已经在多个操作系统和解释器上进行了测试,唯一表现出意外行为的操作系统和解释器是从 apt
获取的 Ubuntu 14.04 Python 3.4.0。在此系统上,我们还验证了当引发完全不相关的异常时似乎也会发生这种情况...
Python 3.4.0 (default, Apr 11 2014, 13:05:18)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> raise Exception('uh oh')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: uh oh
>>> import urllib
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'error', 'parse', 'request', 'response']
这是怎么回事?
最佳答案
您有Apport安装了Ubuntu用来捕获软件崩溃的软件包。
该软件包包含一个安装 sys.excepthook
function 的 Python 软件包;每当 Python 程序中引发未处理异常时,就会调用此钩子(Hook)。该钩子(Hook)的实现间接加载 urllib.*
模块。
通过在交互式解释器中触发异常,您触发了 Hook ,导致运行额外的 Python 代码,从而添加导入。
请参阅apport_python_hook.py
source code ;当调用钩子(Hook)时,会加载各种 apport
模块,包括 apport.report
它导入 urllib
模块。
您可以通过在 /etc/default/apport
中设置 enabled = 0
来禁用该 Hook 。
将来,如果您想看到导入发生,您可以使用-v
command-line switch运行Python。或设置PYTHONVERBOSE
environment variable ;这会告诉您在打开 Python 时加载了 apport_python_hook
模块,并且在引发异常时加载了更多模块。
关于python - 在 python 3.5.x 中使用 `urllib` 意外加载模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46496520/