Семантика оператора импорта python - программирование

Семантика оператора импорта python

Я начинающий python, и мне трудно понять оператор импорта и его варианты.

Предположим, что я использую модуль lxml для очистки веб-сайтов.

В примерах показано,

from lxml.html import parse
parse( 'http://somesite' )

Руководство по стилю python Google предпочитает основной оператор импорта, чтобы сохранить пространства имен. Я бы предпочел сделать это, но когда я попробую:

import lxml
lxml.html.parse( 'http://somesite' )

Появляется следующее сообщение об ошибке:

AttributeError: объект 'module' не имеет атрибута 'html'

Может ли кто-нибудь помочь мне понять, что происходит? Я бы предпочел использовать модули в своих пространствах имен, но вам нужна помощь в понимании семантики.

Большое значение.

4b9b3361

Ответ 1

import lxml.html as LH
doc = LH.parse('http://somesite')

lxml.html является модулем. Когда вы import lxml, модуль html не импортируется в пространство имен lxml. Это решение разработчика. Некоторые пакеты автоматически импортируют некоторые модули, некоторые - нет. В этом случае вы должны сделать это самостоятельно с помощью import lxml.html.

import lxml.html as LH импортирует модуль html и связывает его с именем LH в текущем пространстве имен модулей. Таким образом, вы можете получить доступ к функции parse с помощью LH.parse.


Если вы хотите глубже погрузиться, когда пакет (например, lxml) автоматически импортирует модули (например, lxml.html), откройте терминал и введите

In [16]: import lxml

In [17]: lxml
Out[17]: <module 'lxml' from '/usr/lib/python2.7/dist-packages/lxml/__init__.pyc'>

Здесь вы видите путь к файлу lxml package __init__.py. Если вы посмотрите на содержимое, которое вы обнаружите, оно пустое. Таким образом, никакие подмодули не импортируются. Если вы посмотрите в numpy __init__.py, вы увидите много кода, среди которых

import linalg
import fft
import polynomial
import random
import ctypeslib
import ma

Это все подмодули, которые импортируются в пространство имен numpy. Поэтому с точки зрения пользователя import numpy автоматически предоставляет вам доступ к numpy.linalg, numpy.fft и т.д.

Ответ 2

Возьмем пример пакета pkg с двумя модулями в нем a.py и b.py:

--pkg
   |
   | -- a.py
   |
   | -- b.py
   |
   | -- __init__.py

в __init__.py вы импортируете a.py и не b.py:

импортировать

Итак, если вы открываете терминал и выполняете:

>>> import pkg
>>> pkg.a
>>> pkg.b
AttributeError: 'module' object has no attribute 'b'

Как вы можете видеть, поскольку мы импортировали a.py в pkg __init__.py, мы смогли получить к нему доступ как атрибут pkg, но b там нет, поэтому для доступа к этому позже мы должны использовать:

>>> import pkg.b   # OR: from pkg import b

НТН,

Ответ 3

Когда вы import пакет, интерпретатор просматривает пакет на pythonpath, затем, если найден, анализирует и запускает пакет __init__.py, строит из него объект пакета и вставляет этот объект в sys.modules, Когда importing модуль, он делает то же самое, кроме того, что создает и добавляет объект модуля. Когда вы впоследствии пытаетесь получить доступ к атрибуту (также как метод-член, класс, подмодуль или подпакет), он извлекает соответствующий объект из sys.modules и пытается выполнить getattr в модуле или объекте пакета для нужного вам ребенка. Однако, если дочерний объект является подмодулем или подпакетом, который еще не был imported, он не был добавлен в sys.modules или список атрибутов модуля или пакета, поэтому вы получите AttributeError. Таким образом, вы должны явно импортировать модуль или пакет либо в свой код, либо делегировать его в пакете __init__.py, чтобы он был доступен во время выполнения для его родителя.