python - tutorial - ¿Qué sucede cuando un módulo se importa dos veces?
the django project (3)
Cualquier script de Python recargará un módulo solo una vez. Para recargarlo, utiliza:
reload() # Python 2
y
imp.reload() # Python 3
Tengo una duda de que me gustaría aclararme.
Considere el siguiente módulo llamado ex_1.py
:
print("Hello, I''m ex_1")
def greet(name):
print("Hello, "+name+" nice to meet you! ")
Ahora considere otro archivo llamado 1_client_ex_1.py
que importará el módulo ex_1.py
.
import ex_1.py
Ahora cuando ejecuto este archivo, obtengo la salida como:
Hello, I''m ex_1
Como se esperaba.
Pero cuando cambio a 1_client_ex_1.py
a:
import ex_1.py
import ex_1.py
y ejecutarlo, todavía imprime solo Hello, I''m ex_1
una vez. ¿No debería imprimirlo dos veces?
El módulo solo se carga la primera vez que se ejecuta la instrucción de import
. Véase también reload()
y esta pregunta . Puede examinar sys.modules
para averiguar qué módulos ya se han cargado.
Nada, si un módulo ya ha sido importado, no se vuelve a cargar.
Simplemente obtendrá una referencia al módulo que ya se ha importado (provendrá de sys.modules
).
Para obtener una lista de los módulos que ya se han importado, puede buscar sys.modules.keys()
(tenga en cuenta que urllib
aquí importa muchos otros módulos):
>>> import sys
>>> print len(sys.modules.keys())
44
>>> print sys.modules.keys()
[''copy_reg'', ''sre_compile'', ''_sre'', ''encodings'', ''site'', ''__builtin__'', ''sysconfig'', ''__main__'', ''encodings.encodings'', ''abc'', ''posixpath'', ''_weakrefset'', ''errno'', ''encodings.codecs'', ''sre_constants'', ''re'', ''_abcoll'', ''types'', ''_codecs'', ''encodings.__builtin__'', ''_warnings'', ''genericpath'', ''stat'', ''zipimport'', ''_sysconfigdata'', ''warnings'', ''UserDict'', ''encodings.utf_8'', ''sys'', ''virtualenvwrapper'', ''_osx_support'', ''codecs'', ''readline'', ''os.path'', ''sitecustomize'', ''signal'', ''traceback'', ''linecache'', ''posix'', ''encodings.aliases'', ''exceptions'', ''sre_parse'', ''os'', ''_weakref'']
>>> import urllib
>>> print len(sys.modules.keys())
70
>>> print sys.modules.keys()
[''cStringIO'', ''heapq'', ''base64'', ''copy_reg'', ''sre_compile'', ''_collections'', ''_sre'', ''functools'', ''encodings'', ''site'', ''__builtin__'', ''sysconfig'', ''thread'', ''_ssl'', ''__main__'', ''operator'', ''encodings.encodings'', ''_heapq'', ''abc'', ''posixpath'', ''_weakrefset'', ''errno'', ''_socket'', ''binascii'', ''encodings.codecs'', ''urllib'', ''sre_constants'', ''re'', ''_abcoll'', ''collections'', ''types'', ''_codecs'', ''encodings.__builtin__'', ''_struct'', ''_warnings'', ''_scproxy'', ''genericpath'', ''stat'', ''zipimport'', ''_sysconfigdata'', ''string'', ''warnings'', ''UserDict'', ''struct'', ''encodings.utf_8'', ''textwrap'', ''sys'', ''ssl'', ''virtualenvwrapper'', ''_osx_support'', ''codecs'', ''readline'', ''os.path'', ''strop'', ''_functools'', ''sitecustomize'', ''socket'', ''keyword'', ''signal'', ''traceback'', ''urlparse'', ''linecache'', ''itertools'', ''posix'', ''encodings.aliases'', ''time'', ''exceptions'', ''sre_parse'', ''os'', ''_weakref'']
>>> import urllib #again!
>>> print len(sys.modules.keys()) #has not loaded any additional modules
70
Vamos a darle un giro:
import sys
>>> sys.modules["foo"] = "bar" # Let''s pretend we imported a module named "foo", which is a string.
>>> print __import__("foo")
bar # Not a module, that''s my string!
Como puede ver, si se encuentra un módulo en sys.modules
, solo obtendrá una nueva referencia al mismo. Eso es.
Tenga en cuenta que esto significa que los módulos deben diseñarse para que no tengan efectos secundarios (como la impresión) cuando se importan .
La recarga de módulos, fuera de una sesión interactiva, tampoco suele ser una buena práctica (aunque tiene sus casos de uso); las otras respuestas detallarán cómo haría esto.