2014-07-21 12 views
7

wiem, że jeśli mogę zaimportować moduł o nazwie import(moduleName), to mogę przeładować ją reload(moduleName)Python: Jak przeładować moduły, które zostały przywiezione z *

Ale ja importowania kilka modułów z Kleene gwiazda:

from proj import * 

Jak mogę je ponownie załadować w tym przypadku?

+9

To jeszcze jeden powód, aby nie używać importu oznaczone gwiazdką. – vaultah

+0

Może możesz spróbować z samym modułem sys. Wyświetlanie wszystkich załadowanych modułów (sys.moduled.keys()) i ponowne ich importowanie (po oczyszczeniu -> sys.modules.clear()) –

+2

@vaultah: Nie rozumiem, co próbujesz powiedzieć. Ten import z oznaczeniem gwiazdowym jest złym pomysłem, dlatego też Python nie daje możliwości ponownego załadowania importowanych gwiazd, mimo że Python zezwala na importowanie z gwiazdką w pierwszej kolejności. Czy istnieje nieodpowiednia przyczyna tej asymetrii? –

Odpowiedz

1

Myślę, że istnieje sposób na ponowne załadowanie wszystkich modułów Pythona. Kod Pythona 2.7 znajduje się poniżej: Zamiast importować moduł matematyczny z gwiazdką, możesz importować wszystko, czego potrzebujesz.

from math import * 
from sys import * 

Alfa = modules.keys() 
modules.clear() 

for elem in Alfa: 
    str = 'from '+elem+' import *' 
    try:  
     exec(str)  
    except: 
     pass 
+1

Rozgrywka, ponieważ działa i to tylko kilka linii, ale nie mogę powiedzieć, że jest * * odpowiedzią na pytanie. Powiedzmy, że testuję swój projekt w powłoce, więc robię "z projportu *", a teraz naprawiam coś w jednym z modułów proj i chcę przeładować. Czy powinienem napisać specjalną funkcję, żeby to zrobić? Kiedy importuję moduł po nazwie, muszę tylko wywołać funkcję reload() w tym module. Python zezwala na import z gwiazdką, ale nie zapewnia ponownego załadowania tych oznaczonych gwiazdką modułów importu? –

0

Jest to skomplikowany i mylący problem. Metoda, którą daję, przeładuje moduł i odświeży zmienne w danym kontekście. Jednak ta metoda zostanie przewrócona, jeśli masz wiele modułów używających oznaczonego gwiazdką importu dla danego modułu, ponieważ zachowają one swoje pierwotne wartości zamiast aktualizować. Ogólnie rzecz biorąc, nawet przeładowanie modułu jest czymś, czego nie powinieneś robić, z wyjątkiem sytuacji, gdy pracujesz z REPL. Moduły nie są czymś, co powinno być dynamiczne. Powinieneś rozważyć inne sposoby dostarczania potrzebnych aktualizacji.

import sys 

def reload_starred(module_name, context): 
    if context in sys.modules: 
     context = vars(sys.modules[context]) 
    module = sys.modules[module_name] 

    for name in get_public_module_variables(module): 
     try: 
      del context[name] 
     except KeyError: 
      pass 

    module = reload(module) 

    context.update(get_public_module_variables(module)) 

def get_public_module_variables(module): 
    if hasattr(module, "__all__"): 
     return dict((k,v) for (k,v) in vars(module).items() 
       if k in module.__all__) 
    else: 
     return dict((k,v) for (k,v) in vars(module).items() 
       if not k.startswith("_")) 

Zastosowanie:

reload_starred("my_module", __name__) 
reload_starred("my_module", globals()) 
reload_starred("my_module", "another_module") 
def function(): 
    from my_module import * 
    ... 
    reload_starred("my_module", locals()) 
Powiązane problemy