2016-08-12 35 views
5

Jaka jest różnica między from foo import bar i import foo.bar as bar?Wyjaśnienie dotyczące importu Python

Czy istnieją różnice w zakresie przestrzeni nazw i zakresu Pythona? Jeśli chcesz użyć czegoś z bar (powiedzmy, funkcja o nazwie whatever), możesz nazwać to jako bar.whatever() przy użyciu dowolnej metody.

Widzę oba style importu w bazie kodu, nad którą pracuję, i zastanawiałem się, jakie różnice pociągają za sobą, jeśli w ogóle, i co byłoby uważane za bardziej "Pythoniczne" podejście.

Odpowiedz

4

Jest różnica, zarówno gdy jest moduł bar lub pakiet wewnątrz opakowania foo, a jeśli bar jest nie moduł wcale.

zważył, co następuje foo pakiet:

foo/ 
    __init__.py 
    bar.py 

Jeśli plik __init__.py definiuje globalną nazwę barzbyt, to pierwszy przykład zaimportuje tego obiektu. Drugi przykład zaimportuje moduł bar.py.

Jednak, gdy moduł foo.bar został przywieziony, maszyny import Python ustawić nazwę bar w pakiecie foo, zastępując dowolną istniejącą wcześniej bar globalny __init__.py:

$ ls -1 foo/ 
__init__.py 
bar.py 
$ cat foo/__init__.py 
bar = 'from the foo package' 
$ cat foo/bar.py 
baz = 'from the foo.bar module' 
$ python 
Python 2.7.12 (default, Aug 3 2016, 18:12:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from foo import bar 
>>> bar 
'from the foo package' 
>>> import foo.bar as bar 
>>> bar 
<module 'foo.bar' from 'foo/bar.pyc'> 
>>> bar.baz 
'from the foo.bar module' 
>>> from foo import bar 
>>> bar 
<module 'foo.bar' from 'foo/bar.pyc'> 

Druga sprawa to gdzie dostępny jest podmoduł no bar.py. foo może być pakietem lub prostym modułem. W takim przypadku from foo import bar będą zawsze szukać przedmiotu w module foo i import foo.bar as bar zawsze niepowodzeniem:

$ cat foo.py 
bar = 'from the foo module' 
$ python 
Python 2.7.12 (default, Aug 3 2016, 18:12:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import foo 
>>> foo.bar 
'from the foo module' 
>>> from foo import bar 
>>> bar 
'from the foo module' 
>>> import foo.bar as bar 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named bar 

Należy zauważyć, że we wszystkich przypadkach, w których import powiedzie, możesz skończyć z globalną nazwą bar związany coś, albo obiekt z modułu, albo obiekt modułu.

5

Kiedy pasek nie jest modułem, istnieje ogromna różnica:

# foo.py 
bar = object() 

Tutaj from foo import bar byłoby normalne w Pythonie, ale import foo.bar as bar by podnieść ImportError: No module named bar.

Zwykle używamy konstruktu "as" do aliasu nazwy: albo do dodania kontekstu do nazwy, aby poprawić czytelność, albo aby uniknąć konfliktu z inną nazwą.