369 Stimmen

von ... importieren" gegenüber "importieren".

Ich frage mich, ob es einen Unterschied gibt zwischen dem Codefragment

from urllib import request

und das Fragment

import urllib.request

oder ob sie austauschbar sind. Wenn sie austauschbar sind, welches ist die "Standard"/"bevorzugte" Syntax (falls es eine gibt)?

319voto

g.d.d.c Punkte 44201

Es hängt davon ab, wie Sie auf den Import zugreifen wollen, wenn Sie sich auf ihn beziehen.

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

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

Der Einfachheit halber oder um die Maskierung von eingebauten Elementen zu vermeiden, können Sie beim Import auch Aliasnamen verwenden:

from os import open as open_
# lets you use os.open without destroying the 
# built in open() which returns file handles.

249voto

James Punkte 14623

Viele Menschen haben bereits erklärt, dass import gegen from Deshalb möchte ich versuchen, ein wenig mehr unter der Haube zu erklären, wo der eigentliche Unterschied liegt.

Lassen Sie mich zunächst genau erklären, was die grundlegenden Importanweisungen bewirken.

import X

Importiert das Modul X und erstellt einen Verweis auf dieses Modul in der Datei aktuellen Namespace. Dann müssen Sie den vollständigen Modulpfad zu auf ein bestimmtes Attribut oder eine Methode innerhalb des Moduls zuzugreifen (z.B.: X.name o X.attribute )

from X import *

Importiert das Modul X und erstellt Verweise auf alle öffentlichen Objekte die von diesem Modul im aktuellen Namespace definiert werden (d.h. alles, was das nicht einen Namen hat, der mit _ ) oder welcher Name auch immer Sie erwähnt haben.

Oder anders ausgedrückt, nachdem Sie diese Anweisung ausgeführt haben, können Sie einfach einen einfachen (unqualifizierten) Namen verwenden, um auf Dinge zu verweisen, die im Modul X . Aber X selbst ist nicht definiert, so dass X.name funktioniert nicht. Und wenn name bereits definiert war, wird sie durch die neue Version ersetzt. Und wenn name in X ist geändert wird, um auf ein anderes Objekt zu verweisen, wird Ihr Modul dies nicht bemerken.

Dadurch werden alle Namen des Moduls im lokalen Namensraum verfügbar.

Nun wollen wir sehen, was passiert, wenn wir das tun import X.Y :

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

Siehe sys.modules mit Namen os y 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'>

Siehe globals() y locals() Namespace dict mit Name os y 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'
>>>    

Aus dem obigen Beispiel geht hervor, dass nur os zu den lokalen und globalen Namespaces hinzugefügt wird. Wir sollten also in der Lage sein, Folgendes zu verwenden 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'>
 >>>

aber nicht path :

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

Sobald Sie die os de locals() Namespace, können Sie entweder nicht auf os o os.path auch wenn es sie in 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
>>>

Sehen wir uns nun an from .

from

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

Siehe sys.modules mit Namen os y 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'>

Also sys.modules sieht genauso aus wie beim Import mit import name .

Ja. Schauen wir nach, was es mit dem locals() y globals() Namespace-Dicts aussehen:

>>> 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'
>>>

Sie können den Zugang über path , aber nicht von 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
>>>

Löschen wir 'path' aus locals():

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

Ein letztes Beispiel mit Aliasing:

>>> 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'>
>>>

Und kein Pfad definiert:

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

Ein Fallstrick bei der Verwendung von from

Wenn Sie denselben name aus zwei verschiedenen Modulen:

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

Statistik importieren aus shutil wieder:

>>>
>>> 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'>
>>>

DER LETZTE IMPORT WIRD GEWINNEN

29voto

Anas Elghafari Punkte 1012

Es gibt einen Unterschied. In manchen Fällen funktioniert das eine und das andere nicht. Hier ist ein Beispiel: Nehmen wir an, wir haben die folgende Struktur:

foo.py
mylib\
    a.py
    b.py

Nun möchte ich Folgendes importieren b.py en a.py . Und ich möchte importieren a.py a foo . Wie kann ich das tun? Zwei Anweisungen, in a Ich schreibe:

import b

En foo.py Ich schreibe:

import mylib.a

Nun, dies wird eine ImportError beim Versuch der Ausführung foo.py . Der Interpreter wird sich über die Import-Anweisung in a.py ( import b ), die besagt, dass es kein Modul b gibt. Wie kann man dies also beheben? In einer solchen Situation kann man die import-Anweisung in a a import mylib.b wird nicht funktionieren, da a y b sind beide in mylib . Die Lösung (oder zumindest eine Lösung) ist hier die Verwendung des absoluten Imports:

from mylib import b

Quelle: Python: Importieren eines Moduls, das ein Modul importiert

4voto

Senthil Kumaran Punkte 50813

Sie verwenden Python3 und haben urllib im Paket. Beide Formen sind akzeptabel und keine Form des Imports wird gegenüber der anderen bevorzugt. Manchmal, wenn mehrere Paketverzeichnisse involviert sind, können Sie die erste Form verwenden from x.y.z.a import s

In diesem speziellen Fall mit dem Paket urllib ist der zweite Weg import urllib.request und Verwendung von urllib.request ist, wie die Standardbibliothek sie einheitlich verwendet.

2voto

tkone Punkte 21072

Zumindest in Python 2.x können Sie nicht import urllib2.urlopen

Sie müssen Folgendes tun 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
>>>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X