2012-10-26 18 views
14

Jestem początkującym pytonem i mam problem ze zrozumieniem instrukcji importu i jej odmian.Instrukcja importowania python semantyka

Załóżmy, że używam modułu lxml do skrobania witryn.

Przykłady pokazują,

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

przewodnik redakcyjny pyton Google preferuje podstawowe instrukcji import, w celu zachowania przestrzeni nazw. Wolałbym, aby to zrobić, ale gdy próbuję:

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

otrzymuję następujący komunikat o błędzie:

AttributeError: 'module' object has no attribute 'html'

Czy ktoś może mi pomóc zrozumieć, co się dzieje? Wolałbym używać modułów w/w ich przestrzeniach nazw, ale potrzebuję pomocy w zrozumieniu semantyki.

Bardzo doceniane.

Odpowiedz

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

lxml.html to moduł. Po dodaniu import lxml moduł html nie zostanie zaimportowany do przestrzeni nazw lxml. To decyzja dewelopera. Niektóre pakiety automatycznie importują niektóre moduły, inne nie. W takim przypadku musisz to zrobić samodzielnie, pod numerem import lxml.html.

import lxml.html as LH importuje moduł html i łączy go z nazwą LH w obszarze nazw bieżącego modułu. Możesz więc uzyskać dostęp do funkcji analizy paczek za pomocą LH.parse.


Jeśli chcesz wniknąć głębiej, gdy opakowanie (jak lxml) importuje moduły (jak lxml.html) automatycznie, otwórz terminal i wpisz

In [16]: import lxml 

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

Tutaj widać ścieżkę do lxml plik __init__.py pakietu. Jeśli spojrzysz na zawartość, znajdziesz ją pustą. Więc żadne submoduły nie są importowane. Jeśli spojrzeć w numpy na __init__.py, można zobaczyć wiele kodu, wśród których jest

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

Są to wszystkie Submoduły które są importowane do przestrzeni nazw numpy. Więc z punktu widzenia użytkownika, import numpy automatycznie daje dostęp do numpy.linalg, numpy.fft itp

+2

Ale wyjaśnij, dlaczego to działa. –

+0

Czy powinienem myśleć o lxml jako pakiecie? Czy istnieje jakiś spójny sposób, aby dowiedzieć się, jakie moduły są automatycznie ładowane do mojego programu? –

+0

@TravisLelue: W Pythonie katalog zawierający '__init __. Py' jest pakietem. Tak więc 'lxml' jest pakietem. Moduł to dowolny plik '.py' w pakiecie. Moja edycja (miejmy nadzieję) wyjaśnia, w jaki sposób można dowiedzieć się, jakie moduły automatycznie zostaną zaimportowane do przestrzeni nazw pakietu. – unutbu

3

Kiedy import pakiet, interpreter wyszukuje pakiet na PYTHONPATH, a następnie, jeśli stwierdzono, analizuje i prowadzi danego pakietu __init__.py, budynek obiekt pakietu z niego i wstawia ten obiekt do sys.modules. Kiedy importing moduł, robi to samo, z wyjątkiem, że tworzy i dodaje obiekt modułu. Gdy później spróbujesz uzyskać dostęp do atrybutu (zwanego również metodą członka, klasą, modułem podległym lub podpakietem), pobierze odpowiedni obiekt z sys.modules i spróbuje uzyskać getattr na module lub obiekcie pakietu dla potrzebnego dziecka. Jeśli jednak dziecko jest modułem częściowym lub podpakietem, który jeszcze nie był imported, nie zostało dodane do sys.modules lub listy atrybutów modułu lub pakietu, więc otrzymasz numer AttributeError.Dlatego musisz jawnie zaimportować moduł lub pakiet, albo w swoim kodzie, albo przekazać w pakiecie __init__.py, aby był dostępny w środowisku wykonawczym na rodzica.

6

Weźmy przykład pakiet pkg z dwóch modułów w nim a.py i b.py:

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

w __init__.py importujesz a.py i nieb.py:

import a

więc jeśli otwórz terminal i wykonaj:

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

Jak widać, ponieważ mamy importowane a.py w pkg na __init__.py, byliśmy w stanie uzyskać dostęp go jako atrybut pkg ale b tam nie ma, tak aby uzyskać dostęp do tego później powinniśmy używać:

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

HTH,

Powiązane problemy