'from ... import' vs ' import.` [duplikat]

To pytanie ma już odpowiedź tutaj:

Zastanawiam się, czy jest jakaś różnica między fragmentem kodu

from urllib import request

I fragment

import urllib.request

Lub jeśli są wymienne. Jeśli są wymienne, co jest składnią "standardową"/"preferowaną" (jeśli jest jeden)?

Dzięki!
Author: Mr. T, 2012-02-25

7 answers

To zależy od tego, jak chcesz uzyskać dostęp do importu, gdy się do niego odwołujesz.

from urllib import request
# access request directly.
mine = request()

import urllib.request
# used as urllib.request
mine = urllib.request()

Możesz również samodzielnie tworzyć aliasy podczas importowania dla uproszczenia lub aby uniknąć maskowania wbudowanych ins:

from os import open as open_
# lets you use os.open without destroying the 
# built in open() which returns file handles.
 180
Author: g.d.d.c,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 06:40:13

Wiele osób już wyjaśniło o import vs from, więc chcę spróbować wyjaśnić nieco bardziej pod maską, gdzie leży rzeczywista różnica.

Po pierwsze, pozwól mi wyjaśnić dokładnie, co robią podstawowe instrukcje importu.

import X

Importuje moduł X i tworzy odniesienie do tego modułu w bieżąca przestrzeń nazw. Następnie należy zdefiniować ukończoną ścieżkę modułu do dostęp do określonego atrybutu lub metody z poziomu modułu (np.: X.name lub X.attribute)

from X import *

Importuje moduł X i tworzy odniesienia do wszystkich obiektów publicznych zdefiniowane przez ten moduł w bieżącej przestrzeni nazw (czyli wszystko to nie ma nazwy zaczynającej się od _) lub jakiejkolwiek nazwy wspomniałeś.

Lub, innymi słowy, po uruchomieniu tego Oświadczenia, można po prostu użyj zwykłej (niekwalifikowanej) nazwy, aby odnosić się do rzeczy zdefiniowanych w module X. Ale X sama w sobie nie jest zdefiniowane, więc X.name nie działa. I jeśli name została już zdefiniowana, została zastąpiona przez nową wersję. I jeśli nazwa w X jest zmieniony, aby wskazać inny obiekt, Twój moduł nie zauważy.

To sprawia, że wszystkie nazwy z modułu są dostępne w lokalnej przestrzeni nazw.

Teraz zobaczmy, co się stanie, gdy zrobimy import X.Y:

>>> import sys
>>> import os.path

Sprawdź sys.modules z nazwą os i os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Sprawdź globals() i locals() przestrzeń nazw dict z nazwą os i os.path:

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>    

Z powyższego przykładu wynika, że tylko os jest dodawana do lokalnych i globalnych przestrzeni nazw. Więc powinniśmy być w stanie użyć os:

 >>> os
 <module 'os' from     
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from      
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

... ale nie path:

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined 
>>>
Po usunięciu osz locals() przestrzeni nazw, nie będziesz mógł uzyskać dostępu ani os, ani os.path, nawet jeśli istnieją one w sys.modules:
>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Spójrzmy teraz na from.

from

>>> import sys
>>> from os import path

Sprawdź sys.modules z nazwą os i os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

Więc sys.modules wygląda tak samo, jak wtedy, gdy importowaliśmy za pomocą import name.

Ok. Sprawdźmy jak wyglądają dicki przestrzeni nazw locals() i globals():
>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>
Możesz uzyskać dostęp za pomocą path, ale nie za pomocą os.path:
>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

Usuńmy 'path' z locals ():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

Ostatni przykład użycia aliasingu:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

I nie zdefiniowano ścieżki:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

Jedna pułapka na używanie from

Gdy importujesz to samo name z dwóch różnych modułów:

>>> import sys
>>> from os import stat
>>> locals()['stat']
<built-in function stat>
>>>
>>> stat
<built-in function stat>

Importuj statystyki z shutil Jeszcze raz:

>>>
>>> from shutil import stat
>>> locals()['stat']
<module 'stat' from 
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>> stat
<module 'stat' from 
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>>

OSTATNI IMPORT WYGRA

 131
Author: James Sapam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-06 14:25:07

Jest bardzo mała różnica w funkcjonalności, ale pierwsza forma jest preferencyjna, jak można to zrobić

from urllib import request, parse, error

Gdzie w drugiej postaci, która musiałaby być

import urllib.request, urllib.parse, urllib.error
I musiałbyś odwołać się do w pełni wykwalifikowanej nazwy, która jest o wiele mniej elegancka.
 29
Author: Karl Barker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-24 23:29:12

Jest różnica. W niektórych przypadkach jeden z nich zadziała, a drugi nie. oto przykład: powiedzmy, że mamy następującą strukturę:

foo.py
mylib\
    a.py
    b.py

Teraz chcę zaimportować b.py na a.py. i chcę importować a.py za foo. Jak to zrobić? Dwie wypowiedzi: w a piszę:

import b

W foo.py piszę:

import mylib.a

Cóż, to wygeneruje ImportError podczas próby uruchomienia foo.py. Tłumacz złoży skargę na oświadczenie importowe w a.py (import b) mówiąc tam nie ma modułu B. więc jak można to naprawić? W takiej sytuacji zmiana instrukcji import w a na import mylib.b nie będzie działać, ponieważ a i b są zarówno w lib. Rozwiązanie tutaj (lub przynajmniej jedno rozwiązanie) polega na użyciu importu bezwzględnego:

from lib import b

Source: Python: importowanie modułu, który importuje moduł

 14
Author: Anas Elghafari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:47

Używasz Python3 były urllib w pakiecie. Obie formy są dopuszczalne i żadna forma importu nie jest preferowana nad drugą. Czasami, gdy jest wiele katalogów pakietów, możesz użyć poprzedniego from x.y.z.a import s

W tym konkretnym przypadku z pakietem urllib, drugim sposobem import urllib.request i użycia urllib.request jest sposób równomiernego użycia biblioteki standardowej.

 3
Author: Senthil Kumaran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-24 23:28:30

W Pythonie 2.x przynajmniej nie możesz zrobić import urllib2.urlopen

Musisz zrobić from urllib2 import urlopen

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib2.urlopen
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named urlopen
>>> import urllib.request
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named request
>>>
 1
Author: tkone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-24 23:30:19

Moja główna Skarga na import urllib.prośba jest taka, że możesz nadal odwoływać się do urllib.parse, mimo że nie jest importowany.

>>> import urllib3.request
>>> urllib3.logging
<module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'>

Również prośba o mnie jest pod urllib3. Python 2.7.4 ubuntu

 0
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 20:20:43