`from … import` vs` import .`

Me pregunto si hay alguna diferencia entre el fragmento de código

from urllib import request 

y el fragmento

 import urllib.request 

O si son intercambiables. Si son intercambiables, ¿cuál es la syntax “estándar” / “preferida” (si la hay)?

¡Gracias!

Depende de cómo desea acceder a la importación cuando se refiere a ella.

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

También puede aliarse cosas cuando importe para simplificar o para evitar el enmascaramiento de complementos integrados:

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

Muchas personas ya han explicado acerca de la import contra, por lo que quiero tratar de explicar un poco más bajo el capó, donde radica la diferencia real.

En primer lugar, permítanme explicar exactamente lo que hacen las declaraciones de importación básicas.

import X

Importa el módulo X y crea una referencia a ese módulo en el espacio de nombres actual. Luego, debe definir la ruta del módulo completado para acceder a un atributo o método particular desde dentro del módulo (por ejemplo: X.name o X.attribute )

from X import *

Importa el módulo X y crea referencias a todos los objetos públicos definidos por ese módulo en el espacio de nombres actual (es decir, todo lo que no tiene un nombre que empiece por _ ) o cualquier nombre que mencione.

O, en otras palabras, después de ejecutar esta statement, simplemente puede usar un nombre simple (no calificado) para referirse a las cosas definidas en el módulo X Pero X sí no está definido, por lo que X.name no funciona. Y si el name ya estaba definido, es reemplazado por la nueva versión. Y si se cambia el nombre en X para que apunte a algún otro objeto, su módulo no se dará cuenta.

Esto hace que todos los nombres del módulo estén disponibles en el espacio de nombres local.

Ahora veamos que pasa cuando import XY :

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

Compruebe sys.modules con el nombre os y os.path :

 >>> sys.modules['os']  >>> sys.modules['os.path']  

Verifique el espacio de nombres globals() y locals() dict con los nombres os y os.path :

  >>> globals()['os']  >>> locals()['os']  >>> globals()['os.path'] Traceback (most recent call last): File "", line 1, in  KeyError: 'os.path' >>> 

Del ejemplo anterior, encontramos que solo se agrega os a los espacios de nombres locales y globales. Por lo tanto, deberíamos poder usar os :

  >>> os  >>> os.path  >>> 

… pero no el path

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

Una vez que elimine el sistema os del espacio de nombres locals() , no podrá acceder ni a os ni a os.path , aunque existan en sys.modules :

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

Ahora veamos from .

from

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

Compruebe sys.modules con el nombre os y os.path :

 >>> sys.modules['os']  >>> sys.modules['os.path']  

Entonces, sys.modules ve igual que cuando import name usando el import name .

Bueno. Vamos a ver cómo se ven los dects del espacio de nombres locals() y globals() :

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

Puedes acceder usando la path , pero no con os.path :

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

Vamos a eliminar ‘ruta’ de los locales ():

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

Un ejemplo final usando aliasing:

 >>> from os import path as HELL_BOY >>> locals()['HELL_BOY']  >>> globals()['HELL_BOY']  >>> 

Y ningún camino definido:

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

Una trampa sobre el uso from

Cuando se importa el mismo name de dos módulos diferentes:

 >>> import sys >>> from os import stat >>> locals()['stat']  >>> >>> stat  

Importar stat desde shutil otra vez:

 >>> >>> from shutil import stat >>> locals()['stat']  >>> stat  >>> 

LA ÚLTIMA IMPORTACIÓN GANARÁ

Hay muy poca diferencia en la funcionalidad, pero la primera forma es preferencial, como puede hacer

 from urllib import request, parse, error 

donde en la segunda forma tendría que haber

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

y tendrías que hacer referencia usando el nombre completo, que es mucho menos elegante.

Hay una diferencia. En algunos casos, uno de ellos funcionará y el otro no. Aquí hay un ejemplo: digamos que tenemos la siguiente estructura:

 foo.py mylib\ a.py b.py 

Ahora, quiero importar b.py en a.py Y quiero importar a.py a foo . ¿Cómo hago esto? Dos afirmaciones, en a yo escribo:

 import b 

En foo.py escribo:

 import mylib.a 

Bueno, esto generará un ImportError al intentar ejecutar foo.py El intérprete se quejará de la statement de importación en a.py ( import b ) y dice que no hay un módulo b. Entonces, ¿cómo se puede solucionar esto? En tal situación, cambiar la statement de importación en a para import mylib.b no funcionará ya que a y b están en mylib . La solución aquí (o al menos una solución) es usar la importación absoluta:

 from mylib import b 

Fuente: Python: importar un módulo que importa un módulo

Está utilizando Python3 fueron urllib en el paquete. Ambas formas son aceptables y ninguna forma de importación es preferida sobre la otra. A veces, cuando hay varios directorios de paquetes involucrados, puede usar el primero from xyza import s

En este caso particular con el paquete urllib, la segunda manera de import urllib.request y el uso de urllib.request es cómo la biblioteca estándar lo usa uniformemente.

En Python 2.x al menos no puedes import urllib2.urlopen

Tienes que hacer 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 "", line 1, in  ImportError: No module named urlopen >>> import urllib.request Traceback (most recent call last): File "", line 1, in  ImportError: No module named request >>> 

Mi queja principal con la importación de urllib.request es que aún puede hacer referencia a urllib.parse aunque no se haya importado.

 >>> import urllib3.request >>> urllib3.logging  

También la solicitud para mí está bajo urllib3. Python 2.7.4 ubuntu