python - 在 python 3.5.x 中使用 `urllib` 意外加载模块

标签 python python-3.x urllib

在某些系统上使用 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/

相关文章:

python - 尝试将 AuthSub 与 google health 结合使用时出现“范围损坏或丢失”错误?

python - 使用 Gspread 和 Python 从 google sheet 获取所有列值

python - HTTP 错误 400 错误请求 python

python - 我认为像 frozenset 和 tuple 这样的不可变类型实际上并没有被复制。这个叫什么?它有什么影响吗?

Python3,beautifulsoup,在特定页面不返回任何内容

python - 获取HTTPConnectionPool数据

python - 从 Pandas 中的 groupby .agg() 或 .apply() 有效地创建全新的数据框?

python - 检查数据框中是否有未命名的列,然后在 Pandas 中返回指示

python - 文件名大小写更改在 CentOs 7 上抛出 Os.error[errno 2] python

python - 检查一个字典的值是否是另一个字典的键