it-swarm.com.de

Wie mache ich globale Importe aus einer Funktion?

Ich befürchte, dass dies ein unordentlicher Weg ist, das Problem anzugehen, aber ... 

angenommen, ich möchte einige Importe in Python vornehmen, die auf bestimmten Bedingungen basieren.

Aus diesem Grund möchte ich eine Funktion schreiben:

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

Wie kann ich nun die importierten Module global verfügbar haben?

Zum Beispiel:

conditional_import_modules(test='bar')
thirdmodule.myfunction()
48

Importierte Module sind nur Variablen - Namen, die an einige Werte gebunden sind. Sie müssen sie also nur importieren und mit dem Schlüsselwort global global machen.

Beispiel:

>>> math
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> def f():
...     global math
...     import math
...
>>> f()
>>> math
<module 'math' from '/usr/local/lib/python2.6/lib-dynload/math.so'>
57

Sie können die Importe in einer Funktion wie folgt global machen:

def my_imports(module_name):
    globals()[module_name] = __import__(module_name)
9
badzil

Diese Funktion könnte die Namen der zu importierenden Module zurückgeben und dann verwenden

mod == __import__(module_name)
2
ChrisB

Sie können die integrierte Funktion __import__ verwenden, um ein Modul mit globalem Gültigkeitsbereich bedingt zu importieren.

So importieren Sie ein Modul der obersten Ebene (denken Sie: import foo):

def cond_import():
  global foo
  foo = __import__('foo', globals(), locals()) 

Import aus einer Hierarchie (denken Sie: import foo.bar):

def cond_import():
  global foo
  foo = __import__('foo.bar', globals(), locals()) 

Import aus einer Hierarchie und einem Alias ​​(think: import foo.bar as bar):

def cond_import():
  global bar
  foo = __import__('foo.bar', globals(), locals()) 
  bar = foo.bar
2
maxschlepzig

Ich mag @badzil Ansatz.

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)

Also etwas, das sich traditionell in einem Klassenmodul befindet:

import numpy as np

import rpy2
import rpy2.robjects as robjects
import rpy2.robjects.packages as rpackages
from rpy2.robjects.packages import importr

Kann in einen globalen Bereich umgewandelt werden:

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)

Kann einige Fehler haben, die ich überprüfen und aktualisieren werde. Das letzte Beispiel könnte auch einen Alias ​​haben, der ein anderer "Kurzname" oder ein Hack wie "importr | aliasimportr" wäre.

1
mshaffer

Ich hatte gerade ein ähnliches Problem, hier ist meine Lösung:

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)

dann irgendwo im Code:

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
1
rafał grabie

Ich mag @ Rafał Grabie Annäherung. Da unterstützt es sogar den Import aller. von os import *

(Obwohl es schlechte Praxis XD ist)

Kein Kommentar erlaubt, aber hier ist eine Python 2.7-Version. 

Auch die Notwendigkeit, die Funktion am Ende aufzurufen, wurde entfernt. 

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