我一直在编写模块,并且所有测试都通过了,但是我发现,当我将模块导入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重命名其中之一。

最佳答案

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

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


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

要解决您的问题,您应该按以下方式导入:

from collections.abc import Hashable

class _List(Hashable):

    def __hash__(self):
        return 0


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

关于python - 为什么我可以在测试中访问collections.abc,但不能在生产环境中访问呢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52798967/

10-10 15:18