Почему из scipy импортирует пространственную работу, в то время как scipy.spatial не работает после импорта scipy?

Я хотел бы использовать scipy.spatial.distance.cosine в своем коде. Я могу импортировать подмодуль spatial, если я делаю что-то вроде import scipy.spatial или from scipy import spatial, но если я просто import scipy вызывает scipy.spatial.distance.cosine(...), возникает следующая ошибка: AttributeError: 'module' object has no attribute 'spatial'.

Что не так со вторым подходом?

Ответ 1

Импорт пакета не импортирует подмодуль автоматически. Вам нужно явно импортировать подмодуль.

Например, import xml не импортирует подмодуль xml.dom

>>> import xml
>>> xml.dom
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'dom'
>>> import xml.dom
>>> xml.dom
<module 'xml.dom' from 'C:\Python27\lib\xml\dom\__init__.pyc'>

Есть исключение, подобное os.path. (сам модуль os импортирует подмодуль в его пространство имен)

>>> import os
>>> os.path
<module 'ntpath' from 'C:\Python27\lib\ntpath.pyc'>

Ответ 2

Это потому, что scipy - это пакет, а не модуль. Когда вы импортируете пакет, вы фактически не загружаете модули внутри, и поэтому package.module вызывает ошибку.

Однако import package.module будет работать, потому что он загружает модуль, а не пакет.

Это стандартное поведение большинства операторов импорта, но есть несколько исключений.

Вот тот же случай для urllib в Python 3:

>>> import urllib
>>> dir(urllib)
['__builtins__', '__cached__', '__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', '__path__', 'error', 'parse', 'request', 'response']

См? там нет подмодулей. Для доступа к его подмодулю мы просим подмодуль:

>>> import urllib.request
>>> 

Надеюсь, что это простое объяснение поможет!