Почему я могу получить доступ к collection.abc в тестах, а не в производстве? - PullRequest
0 голосов
/ 14 октября 2018

Я писал модуль, и все тесты прошли, но я обнаружил, что когда я импортирую модуль в 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 голосов
/ 14 октября 2018

Если вы посмотрите на пакет коллекций, он имеет следующую иерархию:

$ 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.

...