Obawiam się, że jest to bałagan, aby podejść do problemu, ale ...

Powiedzmy, że chcę dokonać importu w Pythonie na podstawie pewnych warunków.

Z tego powodu chcę napisać funkcję:

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

Jak mogę mieć dostępne moduły importowane na całym świecie?

Na przykład:

conditional_import_modules(test='bar')
thirdmodule.myfunction()
67
Giovanni Di Milia 16 sierpień 2012, 19:26

7 odpowiedzi

Najlepsza odpowiedź

Importowane moduły są tylko zmiennymi - nazwy związane z pewnymi wartościami. Więc wszystko, czego potrzebujesz, jest importowanie ich i sprawić, by globalne słowo kluczowe global.

Przykład:

>>> 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'>
74
Roman Bodnarchuk 31 styczeń 2015, 17:04

Możesz sprawić, że import globalny w takiej funkcji:

def my_imports(module_name):
    globals()[module_name] = __import__(module_name)
16
badzil 16 sierpień 2012, 16:25

Możesz użyć wbudowanej funkcji {x0}} do warunkowo Importuj moduł z globalnym zakresem.

Aby zaimportować moduł najwyższego poziomu (myśl: import foo):

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

Importuj z hierarchii (myśl: import foo.bar):

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

Import z hierarchii i aliasu (myśl: import foo.bar as bar):

def cond_import():
  global bar
  foo = __import__('foo.bar', globals(), locals()) 
  bar = foo.bar
4
maxschlepzig 9 październik 2016, 07:46

Właśnie miałem podobny problem, oto moje rozwiązanie:

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)

Następnie w dowolnym miejscu w kodzie:

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
3
rafał grabie 17 październik 2018, 14:25

Lubię podejście @badzila.

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)

Więc coś, co jest tradycyjnie w module klasowym:

import numpy as np

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

Może zostać przekształcony w globalny zakres:

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)

Może mieć jakieś błędy, które weryfikuję i zaktualizuję. Ostatni przykład może również mieć alias, który byłby inny "krótki nazwy" lub hack "importrtr | aliasimportr"

2
mshaffer 22 październik 2017, 19:52

Można mieć tę funkcję zwrócić nazwy modułów, które chcesz zaimportować, a następnie użyj

mod == __import__(module_name)
1
ChrisB 16 sierpień 2012, 15:28

Lubię @ rafał podejście Grabie. Ponieważ nawet wspiera importowanie wszystkich. To z importu OS *

(Mimo że jest złą praktyką XD)

Nie wolno komentować, ale tutaj jest wersja Python 2.7.

Wykorzystano również potrzebę wywołania funkcji na końcu.

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 12 listopad 2018, 04:00