it-swarm.com.de

`from ... import` vs` import .`

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

from urllib import request

und das Fragment

import urllib.request

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

Vielen Dank!

224
wchargin

Es hängt davon ab, wie Sie auf den Import zugreifen möchten, wenn Sie darauf verweisen.

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

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

Sie können Dinge auch selbst als Alias ​​verwenden, wenn Sie der Einfachheit halber importieren oder das Maskieren von eingebauten Objekten vermeiden:

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

Viele Leute haben bereits über import vs from erklärt, deshalb möchte ich versuchen, etwas 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 im aktuellen Namespace. Anschließend müssen Sie den vollständigen Modulpfad definieren, um von innerhalb des Moduls auf ein bestimmtes Attribut oder eine bestimmte Methode zuzugreifen (z. B. X.name oder X.attribute).

from X import *

Importiert das Modul X und erstellt Verweise auf alle öffentlichen Objekte, die von diesem Modul im aktuellen Namespace definiert wurden (dh auf alle Objekte, deren Name nicht mit _ beginnt), oder auf den von Ihnen genannten Namen.

Mit anderen Worten, nachdem Sie diese Anweisung ausgeführt haben, können Sie einfach einen einfachen (nicht qualifizierten) Namen verwenden, um auf in Modul X definierte Dinge zu verweisen. Aber X selbst ist nicht definiert, daher funktioniert X.name nicht. Und wenn name bereits definiert wurde, wird es durch die neue Version ersetzt. Wenn der Name in X so geändert wird, dass er auf ein anderes Objekt verweist, merkt Ihr Modul nichts davon.

Damit stehen alle Namen des Moduls im lokalen Namensraum zur Verfügung.

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

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

Überprüfen Sie sys.modules mit dem Namen os und 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'>

Überprüfen Sie globals() und locals() Namespace dikt mit name os und 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'
>>>    

Im obigen Beispiel haben wir festgestellt, dass nur os zu den lokalen und globalen Namespaces hinzugefügt wird. Also sollten wir os verwenden können:

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

Wenn Sie den os aus dem locals()-Namespace löschen, können Sie weder auf os noch auf os.path zugreifen, obwohl sie in sys.modules vorhanden sind:

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

Schauen wir uns nun from an.

from

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

Überprüfen Sie sys.modules mit dem Namen os und 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'>

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

Okay. Lassen Sie uns überprüfen, wie es in den Namensräumen locals() und globals() aussieht:

>>> 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 mit path zugreifen, aber nicht mit 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' von 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'
>>>

Eine Falle über die Verwendung von from

Wenn Sie dasselbe name aus zwei verschiedenen Modulen importieren:

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

Importiere stat von shutil erneut:

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

150
James Sapam

Es gibt kaum Unterschiede in der Funktionalität, aber das erste Formular wird bevorzugt, wie Sie es tun können

from urllib import request, parse, error

wo in der zweiten form müsste das sein

import urllib.request, urllib.parse, urllib.error

und Sie müssen den vollständig qualifizierten Namen verwenden, der viel weniger elegant ist.

30
Karl Barker

Da ist ein Unterschied. In einigen Fällen funktioniert einer davon und der andere nicht. Hier ist ein Beispiel: Angenommen, wir haben die folgende Struktur:

foo.py
mylib\
    a.py
    b.py

Jetzt möchte ich b.py In a.py Importieren. Und ich möchte a.py Nach foo importieren. Wie mache ich das? Zwei Aussagen in a, die ich schreibe:

import b

In foo.py Schreibe ich:

import mylib.a

Nun, dies wird ein ImportError erzeugen, wenn versucht wird, foo.py Auszuführen. Der Interpreter beschwert sich über die Importanweisung in a.py (import b) Und gibt an, dass kein Modul vorhanden ist. B. Wie kann man das beheben? In einer solchen Situation funktioniert das Ändern der Importanweisung in a in import mylib.b Nicht, da a und b beide in mylib sind. Die Lösung hier (oder mindestens eine Lösung) besteht darin, den absoluten Import zu verwenden:

from mylib import b

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

18
Anas Elghafari

Sie verwenden Python3 waren urllib im Paket. Beide Formen sind akzeptabel und keine Importform wird der anderen vorgezogen. Manchmal, wenn mehrere Paketverzeichnisse betroffen sind, können Sie das frühere from x.y.z.a import s Verwenden.

In diesem speziellen Fall mit dem urllib-Paket verwendet die Standardbibliothek import urllib.request Und die Verwendung von urllib.request Einheitlich.

3
Senthil Kumaran

In python 2.x kannst du zumindest nicht import urllib2.urlopen

Du musst 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
tkone

Meine Hauptbeschwerde bei import urllib.request ist, dass Sie immer noch auf urllib.parse verweisen können, obwohl es nicht importiert wird.

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

Auch Anfrage für mich ist unter urllib3. Python 2.7.4 ubuntu

0
Anonymous