为什么我可以在测试中访问collections.abc,但不能在生产环境中访问呢?

时间:2018-10-14 02:26:38

标签: python module pytest

我一直在编写模块,并且所有测试均已通过,但是我发现,当我将模块导入REPL或可执行文件中时,会得到AttributeError

ilinkedlist.py

import collections


class _List(collections.abc.Hashable):

  def __hash__(self):
    return 0

test_ilinkedlist.py

import ilinkedlist


def test_hash():
  assert hash(ilinkedlist._List()) == 0

测试通过,但这是REPL会话:

Python 3.6.5 (default, Jan  1 1970, 00:00:01) 
[GCC 5.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ilinkedlist
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/luther/learning/python/module-question/ilinkedlist.py", line 4, in <module>
    class _List(collections.abc.Hashable):
AttributeError: module 'collections' has no attribute 'abc'

我还有一个引发相同错误的可执行文件:

#!/usr/bin/env python3

import ilinkedlist

print(hash(ilinkedlist._List()))

为什么abc有时会缺少collections?这怎么可能在测试中起作用而在其他地方却没有?我不相信模块会共享它们的“全局”名称空间,所以我不认为这是造成它的原因。

我的模块必须同时使用collections.abc和顶层abc,因此除非必要,否则我不希望使用import-as重命名其中的一个。

1 个答案:

答案 0 :(得分:1)

如果查看collections包,它具有以下层次结构:

$ tree collections/                                   
  collections/           
  ├── __init__.py        
  └── abc.py             

因此,当您执行import collections时,python会导入__init__.py,其中不包含abc.py

要解决您的问题,您应按以下步骤导入:

from collections.abc import Hashable

class _List(Hashable):

    def __hash__(self):
        return 0

这将确保我们始终从Hashable导入collections.abc

相关问题