¿Cómo hacer importaciones globales desde una función?

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__)