Me temo que esta es una manera desordenada de abordar el problema pero …
digamos que quiero hacer algunas importaciones en Python basadas en algunas condiciones.
Por esta razón quiero escribir una función:
def conditional_import_modules(test): if test == 'foo': import onemodule, anothermodule elif test == 'bar': import thirdmodule, and_another_module else: import all_the_other_modules
Ahora, ¿cómo puedo tener los módulos importados disponibles globalmente?
Por ejemplo:
conditional_import_modules(test='bar') thirdmodule.myfunction()
Los módulos importados son solo variables, nombres vinculados a algunos valores. Así que todo lo que necesita es importarlos y hacerlos globales con palabras clave global
.
Ejemplo:
>>> math Traceback (most recent call last): File "", line 1, in NameError: name 'math' is not defined >>> def f(): ... global math ... import math ... >>> f() >>> math
Puedes hacer las importaciones globales dentro de una función como esta:
def my_imports(module_name): globals()[module_name] = __import__(module_name)
Podría hacer que esta función devuelva los nombres de los módulos que desea importar y luego use
mod == __import__(module_name)
Puede usar la función __import__
para importar condicionalmente un módulo con scope global.
Para importar un módulo de nivel superior (piense: import foo
):
def cond_import(): global foo foo = __import__('foo', globals(), locals())
Importe desde una jerarquía (piense: import foo.bar
):
def cond_import(): global foo foo = __import__('foo.bar', globals(), locals())
Importe de una jerarquía y alias (piense: import foo.bar as bar
):
def cond_import(): global bar foo = __import__('foo.bar', globals(), locals()) bar = foo.bar
Me gusta el enfoque de @badzil.
def global_imports(modulename,shortname = None, asfunction = False): if shortname is None: shortname = modulename if asfunction is False: globals()[shortname] = __import__(modulename) else: globals()[shortname] = eval(modulename + "." + shortname)
Así que algo que está tradicionalmente en un módulo de clase:
import numpy as np import rpy2 import rpy2.robjects as robjects import rpy2.robjects.packages as rpackages from rpy2.robjects.packages import importr
Se puede transformar en un ámbito global:
global_imports("numpy","np") global_imports("rpy2") global_imports("rpy2.robjects","robjects") global_imports("rpy2.robjects.packages","rpackages") global_imports("rpy2.robjects.packages","importr",True)
Puede tener algunos errores, que voy a verificar y actualizar. El último ejemplo también podría tener un alias que sería otro “nombre corto” o un hack como “importr | aliasimportr”
Acabo de tener el problema similar, aquí está mi solución:
class GlobalImport: def __enter__(self): return self def __call__(self): import inspect self.collector = inspect.getargvalues(inspect.getouterframes(inspect.currentframe())[1].frame).locals def __exit__(self, *args): globals().update(self.collector)
entonces, en cualquier parte del código:
with GlobalImport() as gi: import os, signal, atexit, threading, _thread # whatever you want it won't remain local # if only gi() # is called before the end of this block # there you go: use os, signal, ... from whatever place of the module
Me gusta el enfoque @ rafał grabie. Ya que incluso soporta la importación de todos. es decir, desde os importación *
(A pesar de ser una mala práctica XD)
No se permite comentar, pero aquí hay una versión de python 2.7.
También se eliminó la necesidad de llamar a la función al final.
class GlobalImport: def __enter__(self): return self def __exit__(self, *args): import inspect collector = inspect.getargvalues(inspect.getouterframes(inspect.currentframe())[1][0]).locals globals().update(collector) def test(): with GlobalImport() as gi: ## will fire a warning as its bad practice for python. from os import * test() print path.exists(__file__)