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 usartypes.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.