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


Esta pregunta ya tiene una respuesta aquí:

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, que es la sintaxis "estándar"/"preferido" (si hay uno)?

Gracias!

Author: Mr. T, 2012-02-25

7 answers

Depende de cómo desee acceder a la importación cuando se refiera a ella.

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

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

También puede alias cosas a sí mismo cuando se importa por simplicidad o para evitar enmascarar built 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-29 06:40:13

Muchas personas ya han explicado acerca de import vs from, así 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 acceda a un atributo o método particular desde el interior del módulo (e. g.: X.name o X.attribute)

from X import *

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

O, en otras palabras, después de ejecutar esta declaración, simplemente puede use un nombre simple (no calificado) para referirse a las cosas definidas en module X. Pero X no es definido, así que X.name no funciona. Y si name ya estaba definido, se sustituye por la nueva versión. Y si el nombre en X es cambiado para apuntar 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 qué sucede cuando lo hacemos import X.Y:

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

Marque sys.modules con el nombre 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'>

Compruebe globals() y locals() dict de espacio de nombres con nombre 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'
>>>    

Del ejemplo anterior, encontramos que solo se agrega os a los espacios de nombres locales y globales. Por lo tanto, debemos ser capaces de utilizar 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'>
 >>>

But pero no path:

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

Una vez que elimine el os de locals() espacio de nombres, no podrá acceder a os o os.path, aunque existan en 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
>>>

Ahora veamos from.

from

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

Marque sys.modules con el nombre 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'>

Así que sys.modules se ve igual que cuando importamos usando import name.

Bien. Vamos a comprobar cómo se ven los dictados de espacio de nombres locals() y 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'
>>>

Puedes acceder usando path, pero no mediante 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
>>>

Eliminemos 'path' de locals ():

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

Un último ejemplo usando 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'>
>>>

Y ninguna ruta definida:

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

Un escollo sobre el uso de from

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

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

Importar estadísticas de shutil de nuevo:

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

LA ÚLTIMA IMPORTACIÓN GANARÁ

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-06 14:25:07

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

from urllib import request, parse, error

Donde en la segunda forma que tendría que ser

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

Y tendría que hacer referencia usando el nombre completo, que es mucho menos elegante.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-24 23:29:12

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

foo.py
mylib\
    a.py
    b.py

Ahora, quiero importar b.py to a.py. Y quiero importar a.py por foo. ¿Cómo hago esto? Dos declaraciones: En a 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 declaración de importación en a.py (importación b) diciendo allí no hay módulo b. Entonces, ¿cómo se puede arreglar esto? En tal situación, cambiar la instrucción import en a para importar mylib.b no funcionará ya que a y b están ambos en lib. La solución aquí (o al menos una solución) es usar importación absoluta:

from lib import b

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

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:47

Está utilizando Python3 were urllib en el paquete. Ambas formas son aceptables y no se prefiere una forma de importación sobre la otra. A veces, cuando hay varios directorios de paquetes involucrados, puede usar el anterior from x.y.z.a import s

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

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-24 23:28:30

En python 2.x al menos no puedes hacer 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 "<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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-24 23:30:19

Mi principal queja con import urllib.la petición es que aún pueda hacer referencia a Urllib.analizar aunque no sea importado.

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

También la solicitud para mí está bajo 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-28 20:20:43