chart python python-3.x python-3.3

python - chart - plt title position



Importar archivo de origen python arbitrario.(Python 3.3+) (3)

¿Cómo puedo importar un archivo fuente python arbitrario (cuyo nombre de archivo podría contener cualquier carácter, y no siempre termina con .py ) en Python 3.3+ ?

Utilicé imp.load_module siguiente manera:

>>> import imp >>> path = ''/tmp/a-b.txt'' >>> with open(path, ''U'') as f: ... mod = imp.load_module(''a_b'', f, path, (''.py'', ''U'', imp.PY_SOURCE)) ... >>> mod <module ''a_b'' from ''/tmp/a-b.txt''>

Todavía funciona en Python 3.3, pero según la documentación imp.load_module , está en desuso:

Obsoleto desde la versión 3.3 : innecesario ya que los cargadores deberían usarse para cargar módulos y find_module () está en desuso.

y la documentación del módulo imp recomienda utilizar importlib :

Nota Los nuevos programas deberían usar importlib en lugar de este módulo.

¿Cuál es la forma correcta de cargar un archivo de origen python arbitrario en Python 3.3+ sin usar la función imp.load_module desuso?


Encontré una solución del código de prueba importlib .

Usando importlib.machinery.SourceFileLoader :

>>> import importlib.machinery >>> loader = importlib.machinery.SourceFileLoader(''a_b'', ''/tmp/a-b.txt'') >>> mod = loader.load_module() >>> mod <module ''a_b'' from ''/tmp/a-b.txt''>

NOTA : solo funciona en Python 3.3+ .

ACTUALIZACIÓN Loader.load_module está en desuso desde Python 3.4. Use Loader.exec_module en Loader.exec_module lugar:

>>> import types >>> import importlib.machinery >>> loader = importlib.machinery.SourceFileLoader(''a_b'', ''/tmp/a-b.txt'') >>> mod = types.ModuleType(loader.name) >>> loader.exec_module(mod) >>> mod <module ''a_b''>

>>> import importlib.machinery >>> import importlib.util >>> loader = importlib.machinery.SourceFileLoader(''a_b'', ''/tmp/a-b.txt'') >>> spec = importlib.util.spec_from_loader(loader.name, loader) >>> mod = importlib.util.module_from_spec(spec) >>> loader.exec_module(mod) >>> mod <module ''a_b'' from ''/tmp/a-b.txt''>


Similar a @falsetru pero para Python 3.5+ y teniendo en cuenta lo que importlib documento importlib sobre el uso de importlib.util.module_from_spec sobre types.ModuleType :

Esta función [ importlib.util.module_from_spec ] es preferible a usar types.ModuleType para crear un nuevo módulo ya que la especificación se usa para establecer tantos atributos de importación controlada en el módulo como sea posible.

Solo podemos importar cualquier archivo con importlib modificando la lista importlib.machinery.SOURCE_SUFFIXES .

import importlib importlib.machinery.SOURCE_SUFFIXES.append('''') # empty string to allow any file spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # if desired: importlib.machinery.SOURCE_SUFFIXES.pop()


Versión más corta de la solución de @falsetrue:

>>> import importlib.util >>> spec = importlib.util.spec_from_file_location(''a_b'', ''/tmp/a-b.py'') >>> mod = importlib.util.module_from_spec(spec) >>> spec.loader.exec_module(mod) >>> mod <module ''a_b'' from ''/tmp/a-b.txt''>

Lo probé con Python 3.5 y 3.6.

De acuerdo con los comentarios, no funciona con extensiones de archivo arbitrarias.