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