Kako iskrcati (reload) python modul?

Imam dugačak Python poslužitelj i želite ažurirati uslugu bez ponovnog pokretanja poslužitelja. Koji je najbolji način da to učinite?

 if foo.py has changed: unimport foo <-- How do I do this? import foo myfoo = foo.Foo() 
640
13 янв. Mark Harrison postavljen je 13. siječnja 2009-01-13 03:33 '09 u 3:33 am 2009-01-13 03:33
@ 19 odgovora

Modul možete ponovno učitati kada je već uvezen pomoću ugrađene funkcije reload :

 from importlib import reload # Python 3.4+ only. import foo while True: # Do some things. if is_changed(foo): foo = reload(foo) 

U Pythonu 3, reload premješteno u imp modul. U 3.4, imp je odbačen u korist importlib , a posljednjem reload dodano reload . Kada ciljate na 3 ili noviju verziju, pogledajte odgovarajući modul kada pozovete reload ili ga uvezete.

Mislim da je to ono što želiš. Web poslužitelji, kao što je Django razvojni poslužitelj, koriste ovo tako da možete vidjeti učinke promjena koda bez ponovnog pokretanja samog poslužiteljskog procesa.

Citat iz dokumenata:

Kod Python modula se ponovno kompajlira, a kod modula se ponovno instalira, definirajući novi skup objekata povezanih s imenima u modularnom rječniku. Init funkcija modula proširenja se ne poziva drugi put. Kao i svi drugi objekti u Pythonu, stari objekti se obnavljaju tek nakon što njihovi referentni brojevi padnu na nulu. Imena u prostoru naziva modula se ažuriraju kako bi ukazala na nove ili promijenjene objekte. Druge reference na stare objekte (na primjer, imena izvan modula) ne vraćaju se na nove objekte i moraju se ažurirati u svakom prostoru imena gdje se nalaze, ako je potrebno.

Kao što ste primijetili u svom pitanju, morat ćete vratiti Foo objekte ako je Foo klasa u modulu foo .

581
13 янв. odgovor dao cdleary siječanj 13 2009-01-13 03:34 '09 u 3:34 2009-01-13 03:34

U Python 3.0-3.3 trebate koristiti: imp.reload(module)

BDFL je odgovorio na to pitanje.

Međutim, imp zastario u 3.4, u korist importlib (zahvaljujući @ Stefan! ).

Mislim da je razlog zašto youd sada koristiti importlib.reload(module) , iako Im ne siguran.

237
10 окт. odgovor koji je dao Paul D. Waite 10. listopada. 2009-10-10 16:36 '09 u 16:36 2009-10-10 16:36

Može biti posebno teško ukloniti modul ako nije čisti Python.

Evo nekih informacija iz: Kako mogu ukloniti uvezeni modul?

Možete koristiti sys.getrefcount () da biste saznali stvarni broj veza.

 >>> import sys, empty, os >>> sys.getrefcount(sys) 9 >>> sys.getrefcount(os) 6 >>> sys.getrefcount(empty) 3 

Brojevi veći od 3 pokazuju da će biti teško riješiti se modula. Home "prazan" (ne sadrži ništa) modul bi trebao biti smeće prikupljeni nakon

 >>> del sys.modules["empty"] >>> del empty 

budući da je treća veza artefakt funkcije getrefcount ().

76
28 янв. Odgovor koji je dao Gregg Lind 28. siječnja 2009-01-28 17:03 '09 u 17:03 2009-01-28 17:03

reload(module) , ali samo ako je potpuno autonoman. Ako bilo što drugo ima vezu na modul (ili bilo koji objekt koji pripada modulu), dobit ćete suptilne i znatiželjne pogreške uzrokovane činjenicom da stari kôd visi duže nego što ste očekivali, a stvari kao što je isinstance ne rade s različitim verzije istog koda.

Ako imate jednosmjerne ovisnosti, morate ponovno učitati sve module koji ovise o ponovno učitanom modulu da biste se riješili svih referenci na stari kod. Zatim ponovno učitajte module koji ovise o ponovno učitanim modulima.

Ako imate kružne ovisnosti, što je vrlo uobičajeno, na primjer, kada se bavite ponovnim učitavanjem paketa, morate istodobno isprazniti sve module u grupi. To ne možete učiniti s ponovnim reload() , jer će ponovno uvesti svaki modul prije ažuriranja zavisnosti, što će omogućiti korištenje starih veza za uvlačenje u nove module.

Jedini način da to učinite u ovom slučaju je razbijanje sys.modules , koji nije podržan. Morat ćete proći i izbrisati svaki unos sys.modules koji želite ponovno učitati u sljedećem uvozu, kao i izbrisati unose čije su vrijednosti None da biste riješili problem implementacije vezan uz predmemoriranje, ako relativni uvoz nije uspio. To nije baš ugodno, ali sve dok imate potpuno autonoman skup zavisnosti koji ne ostavlja linkove izvan baze koda, radi.

Vjerojatno je najbolje ponovno pokrenuti poslužitelj: -)

59
13 янв. odgovor je dat bobince 13 jan. 2009-01-13 15:53 '09 u 15:53 2009-01-13 15:53
 if 'myModule' in sys.modules: del sys.modules["myModule"] 
54
07 июля '10 в 14:44 2010-07-07 14:44 Odgovor daje Kumaresan 07. srpnja 2007. u 14:44 2010-07-07 14:44

Za Python 2, upotrijebite ugrađenu funkciju reload () :

 reload(module) 

Za Python 2 i 3.2-3.3 koristite reload iz imp modula :

 import imp imp.reload(module) 

Ali imp ne preporučuje iz verzije 3.4 u korist importlib , zato upotrijebite:

 import importlib importlib.reload(module) 

ili

 from importlib import reload reload(module) 
37
09 авг. odgovor je dan goetzc 09 aug. 2015-08-09 20:28 '15 u 20:28 2015-08-09 20:28

Sljedeći kod vam omogućuje kompatibilnost s Python 2/3:

 try: reload except NameError: # Python 3 from imp import reload 

Možete ga koristiti kao reload() u obje verzije, što pojednostavljuje postupak.

20
20 нояб. Odgovor je dao Matt Clarkson 20. studenog 2012-11-20 19:01 '12 u 7:01 pm 2012-11-20 19:01

Prihvaćeni odgovor ne rješava slučaj X uvoza Y. Ovaj kôd obrađuje ga i standardni slučaj uvoza:

 def importOrReload(module_name, *names): import sys if module_name in sys.modules: reload(sys.modules[module_name]) else: __import__(module_name, fromlist=names) for name in names: globals()[name] = getattr(sys.modules[module_name], name) # use instead of: from dfly_parser import parseMessages importOrReload("dfly_parser", "parseMessages") 

U slučaju ponovnog pokretanja, dodjeljujemo imena najviših razina vrijednostima pohranjenim u novom modulu za ponovno podizanje sustava, koji ih ažurira.

14
28 сент. odgovor dao Joseph Garvin na 28 sep. 2014-09-28 02:30 '14 u 2:30 2014-09-28 02:30

Ovo je moderan način ponovnog pokretanja modula:

 from importlib import reload 

Samo upišite reload(MODULE_NAME) , zamjenjujući MODULE_NAME nazivom modula koji želite ponovno učitati.

Na primjer, reload(math) ponovno učitava matematičku funkciju.

7
21 нояб. Odgovor koji je dao Richie Bendall 21. studenog 2017-11-21 21:04 '17 u 21:04 2017-11-21 21:04

Za ljude poput mene koji žele istovariti sve module (kada su pokrenuti u Python interpreteru pod Emacsom ):

  for mod in sys.modules.values(): reload(mod) 

Više informacija nalazi se u Reloading Python modulima .

6
08 мая '10 в 19:50 2010-05-08 19:50 odgovor je dat Arkadiy 08 svibanj '10 u 19:50 2010-05-08 19:50

Ako niste na poslužitelju, ali se razvijate i trebate često učitati modul, ovdje je dobar savjet.

Prvo provjerite koristite li izvrsnu IPython ljusku iz projekta Jupyter Notebook. Nakon instalacije Jupytera, možete ga pokrenuti pomoću ipython ili jupyter console ili još bolje, jupyter qtconsole , koji će vam dati lijepu boju s konzolnim kodom u bilo kojem OS-u.

Sada unesite:

 %load_ext autoreload %autoreload 2 

Sada, svaki put kada pokrenete svoju skriptu, vaši će moduli biti ponovno učitani.

Osim 2 , postoje i druge opcije za magiju pokretanja :

 %autoreload Reload all modules (except those excluded by %aimport) automatically now. %autoreload 0 Disable automatic reloading. %autoreload 1 Reload all modules imported with %aimport every time before executing the Python code typed. %autoreload 2 Reload all modules (except those excluded by %aimport) every time before executing the Python code typed. 
6
18 марта '18 в 16:46 2018-03-18 16:46 odgovor je dat Neves 18. ožujka '18 u 16:46 2018-03-18 16:46

Enthought Traits ima modul koji dobro radi za to. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

Ponovno će učitati modificirani modul i ažurirati druge module i objekte koji ga koriste. Ne radi većinu vremena s metodama __very_private__ i može __very_private__ naslijediti klase, ali mi štedi vrijeme od ponovnog pokretanja host aplikacije kada pišem PyQt guis ili stvari koje se pokreću u programima kao što su Maya ili Nuke. možda u 20-30% slučajeva, ali je još uvijek nevjerojatno korisno.

Enthought ne ponovno učitava datoteke u trenutku kada se promijene - morate ga nazvati eksplicitno - ali to ne mora biti tako teško provesti ako vam je stvarno potreban.

5
09 янв. odgovor je dan flipthefrog Jan 09 2016-01-09 04:06 '16 u 4:06 2016-01-09 04:06

2018/02/01

  1. modul foo mora biti uspješno uvezen.
  2. from importlib import reload , reload(foo)

31.5. importlib - implementacija uvoza - Python 3.6.4 dokumentacija

2
01 февр. Odgovor daje JawSaw 01. veljače. 2018-02-01 06:44 '18 u 6:44 ; 2018-02-01 06:44

Oni koji koriste python 3 i ponovno učitati iz importlib.

Ako imate problema kao što je onaj koji izgleda kao da se modul ne pokreće ... To je zato što pyc rekompilira (do 60 sekundi) i potrebno je neko vrijeme da rekompilira. Pišem ovaj savjet samo da biste znali da ste naišli na takav problem.

2
17 мая '18 в 14:00 2018-05-17 14:00 odgovor je dao PythonMan 17. svibnja u 14:00 sati 2018-05-17 14:00

Još jedna mogućnost. Pogledajte da je Python zadana importlib.reload samo knjižnica importlib.reload proslijeđena kao argument. Neće ponovno učitati knjižnice koje uvoze vašu lib. Ako ste promijenili mnogo datoteka i imate kompliciran paket za uvoz, morate napraviti duboko ponovno pokretanje .

Ako imate instaliran IPython ili Jupyter , možete koristiti funkciju za duboko ponovno učitavanje svih liba:

 from IPython.lib.deepreload import reload as dreload dreload(foo) 

Ako nemate Jupyter, instalirajte ga s ovom naredbom u ljusci:

 pip3 install jupyter 
1
08 мая '18 в 21:07 2018-05-08 21:07 odgovorio je na neves 8. svibnja '18 u 21:07 2018-05-08 21:07

za mene, u slučaju Abaqusa, ovako to radi. Zamislite datoteku Class_VerticesEdges.py

 sys.path.append('D:\...\My Pythons') if 'Class_VerticesEdges' in sys.modules: del sys.modules['Class_VerticesEdges'] print 'old module Class_VerticesEdges deleted' from Class_VerticesEdges import * reload(sys.modules['Class_VerticesEdges']) 
1
05 февр. Odgovor daje Matt S 5. veljače. 2016-02-05 17:27 '16 u 17:27 2016-02-05 17:27

Imam puno problema s pokušajima da ponovo uđem nešto u Sublime Text, ali sam napokon uspio napisati ovaj program za ponovno učitavanje modula u Sublime Text na temelju koda sublime_plugin.py za ponovno učitavanje modula.

U donjem primjeru možete ponovno učitati module iz putova s ​​razmacima u njihovim imenima, a zatim nakon ponovnog pokretanja jednostavno možete uvesti kao i obično.

 def reload_module(full_module_name): """ Assuming the folder `full_module_name` is a folder inside some folder on the python sys.path, for example, sys.path as `C:/`, and you are inside the folder `C:/Path With Spaces` on the file `C:/Path With Spaces/main.py` and want to re-import some files on the folder `C:/Path With Spaces/tests` @param full_module_name the relative full path to the module file you want to reload from a folder on the python `sys.path` """ import imp import sys import importlib if full_module_name in sys.modules: module_object = sys.modules[full_module_name] module_object = imp.reload( module_object ) else: importlib.import_module( full_module_name ) def run_tests(): print( "\n\n" ) reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" ) reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" ) from .tests import semantic_linefeed_unit_tests from .tests import semantic_linefeed_manual_tests semantic_linefeed_unit_tests.run_unit_tests() semantic_linefeed_manual_tests.run_manual_tests() if __name__ == "__main__": run_tests() 

Ako lansirate prvi put, to bi trebalo učitati modul, ali ako kasnije možete ponovno koristiti metodu / funkciju run_tests() će učitati testne datoteke. Sa Sublime Textom ( Python 3.3.6 ) to se događa vrlo često, jer se njegov interpreter nikada ne zatvara (osim ako ponovno pokrenete Sublime Text, tj. Python3.3 Interpreter).

0
09 нояб. odgovor je dan korisniku 09 Nov. 2017-11-09 21:36 '17 u 21:36 2017-11-09 21:36

Postupak unload može se jednostavno izvesti na sljedeći način:

 import pythonlib del pythonlib 

s ovom knjižnicom nećete imati više nikakve veze.

-1
16 авг. Odgovor dao Mincă Daniel Andrei 16. kol. 2018-08-16 16:12 '18 u 16:12 2018-08-16 16:12

Drugi način može biti uvoz modula u funkciju. Dakle, kada funkcija završi, modul prima prikupljeno smeće.

-1
12 февр. odgovor dao hackbot89 12. veljače. 2015-02-12 00:13 '15 u 0:13 2015-02-12 00:13

Pogledajte druga pitanja o oznaka ili Ask a Question