En Python, cómo importar el nombre de archivo comienza con un número

83

Básicamente, hay un archivo llamado 8puzzle.pyy quiero importar el archivo a otro archivo (en la misma carpeta y no puedo cambiar el nombre del archivo como se proporciona el archivo). ¿Hay alguna forma de hacer esto en Python? Intenté de la manera habitual from 8puzzle import *, me da un error.

El error es:

>>> import 8puzzle
  File "<input>", line 1
    import 8puzzle
           ^
SyntaxError: invalid syntax
>>> 
Simon Guo
fuente
12
¿Por qué la gente dice "me da [un] error" y luego no publica cuál es el error?
John Zwinck
7
@JohnZwinck Es un error de sintaxis. Supongo que porque "8puzzle" no es un identificador válido (comienza con un número), y la sintaxis de la declaración de importación espera un identificador de Python allí. Lo que haría la respuesta "No, no puede. Cambie el nombre del módulo a algo que comience con una letra o un guión bajo".
millimoose
John hizo un buen punto, lo tendré en cuenta. Y gracias Abhijeet, agrega el mensaje de error para mí. Gracias.
Simon Guo
1
Cambiar el nombre 8puzzle.pyde puzzle8.pyy el uso import puzzle8.
Bakuriu
Véase también stackoverflow.com/questions/6811902/…
tripleee

Respuestas:

94

Podrías hacerlo

puzzle = __import__('8puzzle')

Problema muy interesante. Recordaré no nombrar nada con un número.

Si lo desea import *, debe consultar esta pregunta y respuesta .

Yuji 'Tomita' Tomita
fuente
1
¡Funciona genial! Gracias. sí, no lo nombraría que comience con un número, pero es un archivo de trabajo de asignaturas del curso, así que no puedo cambiar el nombre. Pero parece que no importa, ya que ya tenemos la solución. Gracias de nuevo.
Simon Guo
4
Ayuda a salvar el mundo, o al menos a tus compañeros de clase. Si le dan una importación imposible, comuníqueselo al instructor. Sí, a veces odian equivocarse, pero si usted tiene este problema, todos los demás también y, aunque esta respuesta funciona, no es la solución correcta (a menos que la clase sea "Python 101 ofuscado").
msw
1
Una mejor manera (con Python 2.7 al menos) es usar el módulo 'importlib': puzzle = importlib.import_module ('8puzzle')
Cédric
3
En realidad, hay un buen caso de uso para esto: como parte del proceso de compilación / producción, concatenar módulos de Python juntos es más fácil si se nombran en forma lexigráfica (generalmente no importa, pero las constantes e importaciones en la parte superior, 'if name 'en la parte inferior, por lo que algunos módulos que comienzan con' 0 'pueden ser útiles.) También es útil para depurar un diseño de directorio tan inusual, cuando se combina con inotify o watch, algo como: watch -n .1' cat * | python ', que cargaría su aplicación de Python cada décima de segundo (o al menos lo más rápido posible), o: cat $ (find. -name "* .py") | python
fatal_error
1
Llega tarde a la fiesta, pero se está importando otro caso de uso de las migraciones de Alembic, ya que todas comienzan con hashes aleatorios
kevlarr
35

Las respuestas anteriores son correctas, pero por ahora, la forma recomendada es usar la import_modulefunción:

importlib.import_module(name, package=None)
Importar un módulo. El argumento de nombre especifica qué módulo importar en términos absolutos o relativos (por ejemplo, pkg.modo ..mod). Si el nombre se especifica en términos relativos, entonces el argumento del paquete debe establecerse en el nombre del paquete que actuará como ancla para resolver el nombre del paquete (por ejemplo, import_module('..mod', 'pkg.subpkg')se importará pkg.mod).

La función import_module () actúa como un contenedor simplificador importlib.__import__(). Esto significa que toda la semántica de la función se deriva de importlib.__import__(). La diferencia más importante entre estas dos funciones es que import_module()devuelve el paquete o módulo especificado (por ejemplo pkg.mod), mientras que __import__()devuelve el paquete o módulo de nivel superior (por ejemplo pkg).

Si está importando dinámicamente un módulo que se creó desde que el intérprete comenzó la ejecución (por ejemplo, creó un archivo fuente de Python), es posible que deba llamar invalidate_caches()para que el nuevo módulo sea detectado por el sistema de importación.

__import__ no se recomienda ahora.

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
Una implementación de la __import__()función incorporada.

Nota La importación programática de módulos debe usarse en import_module()lugar de esta función.

laike9m
fuente
Funciona gracias, pero no funciona importar una función o variable dentro de uno de estos archivos comenzando con un número. Si lo hago an_imported_file = importlib.import_module('13_file'), entonces no puedo from an_imported_file import var_x. ¿Hay algo que se pueda hacer para lograrlo?
Martin
/usr/local/bin/python3.7 "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py" Traceback (most recent call last): File "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py", line 7, in <module> from an_imported_file import var_x ModuleNotFoundError: No module named 'an_imported_file'
Martin
Además, la línea `from an_imported_file import var_x` en Pycharm está subrayada en rojo ...
Martin
No lo sé, lo siento. Mi consejo general es evitar hacer esto.
laike9m
0

No use la .pyextensión en sus importaciones.

¿ from 8puzzle import *Funciona?

Por lo que vale, from x import *no es un patrón de Python preferido, ya que sangra el espacio de nombres de ese módulo en su contexto actual.

En general, intente importar cosas que desee específicamente de ese módulo. Se puede importar cualquier global del otro módulo.

por ejemplo, si lo ha hecho 8puzzle.foo, podría hacer desde 8puzzle

Editar:

Si bien mi .pymensaje es correcto, no es suficiente.

La __import__('8puzzle')sugerencia del otro cartel es correcta. Sin embargo, recomiendo encarecidamente evitar este patrón .

Por un lado, está reservado un método Python interno y privado. Básicamente, está rompiendo las suposiciones fundamentales de lo que significa poder importar un módulo. Simplemente cambiar el nombre del archivo por otro, como puzzle8, solucionará esto.

Esto frustrará muchísimo a los programadores de Python experimentados que esperan saber cuáles son sus importaciones en la parte superior y esperan que el código (intente) ajustarse a PEP8 .

mvanveen
fuente
1
perdón por la confusión. Lo que hice fue from 8puzzle import *editar mi pregunta original. Y no funciona como dijo mvanveen.
Simon Guo
Ese es mi mal. Olvidé que los nombres de archivo de los módulos no pueden comenzar con un número. Publiqué una edición.
mvanveen