Vairāk
Kā izkraut (pārlādēt) moduli?
Man ir ilgstoši darbojošs Python serveris, un es vēlētos, lai varētu atjaunināt pakalpojumu, nepārstartējot serveri. Kāds ir labākais veids, kā to izdarīt?
if foo.py has changed:
unimport foo <-- How do I do this?
import foo
myfoo = foo.Foo()
756
3
Ja modulis jau ir importēts, to var pārlādēt, izmantojot iebūvēto funkciju
reload
:Python 3 versijā
reload
tika pārcelta uzimp
moduli. Versijā 3.4imp
tika atcelts par labuimportlib
, unreload
tika pievienots pēdējam. Ja lietojat 3 vai jaunāku versiju, vai nu atsaucieties uz attiecīgo moduli, izsaucotreload
, vai importējiet to.Es domāju, ka tas ir tas, ko jūs vēlaties. Tādi tīmekļa serveri kā Django izstrādes serveris to izmanto, lai jūs varētu redzēt sava koda izmaiņu ietekmi, nepārstartējot pašu servera procesu.
Citējot no dokumentiem:
Python moduļu kods tiek pārkompilēts un pārveidots.
Kā jūs atzīmējāt savā jautājumā, jums būs jāpārveido
Foo
objekti, jaFoo
klase atrodasfoo
modulī.Moduļa dzēšana var būt īpaši sarežģīta, ja tas nav tīrs Python.
Šeit ir sniegta informācija no: How do I really delete an imported module?.
reload(modulis)
, bet tikai tad, ja tas ir pilnīgi autonoms. Ja uz šo moduli (vai kādu citu modulim piederošu objektu) ir atsauce uz ko citu, tad var rasties smalkas un interesantas kļūdas, ko izraisa vecais kods, kas ir saglabājies ilgāk, nekā gaidīts, un tādas lietas kāisinstance
nedarbojas dažādās tā paša koda versijās.Ja jums ir vienvirziena atkarības, jums jāpārlādē arī visi moduļi, kas ir atkarīgi no pārlādētā moduļa, lai atbrīvotos no visām atsaucēm uz veco kodu. Un pēc tam rekursīvi pārlādējiet moduļus, kas ir atkarīgi no pārlādētajiem moduļiem.
Ja ir apļveida atkarības, kas ir ļoti bieži sastopams, piemēram, kad tiek veikta pakotnes pārlādēšana, ir jāizlādē visi grupas moduļi vienā piegājienā. To nevar izdarīt ar
reload()
, jo katrs modulis tiks importēts atkārtoti, pirms tā atkarības ir atjaunotas, tādējādi ļaujot vecajām atsaucēm iefiltrēties jaunajos moduļos.Vienīgais veids, kā to izdarīt šajā gadījumā, ir uzlauzt
sys.modules
, kas nav atbalstīts. Būtu jāiet cauri un jāizdzēš katrssys.modules
ieraksts, kuru vēlaties, lai nākamajā importā tiktu ielādēts no jauna, kā arī jāizdzēš ieraksti, kuru vērtības irNone
, lai risinātu implementācijas problēmu, kas saistīta ar neizdevušos relatīvo importu kešēšanā. Tas nav ļoti jauki, bet, kamēr vien jums ir pilnībā pašpietiekams atkarību kopums, kas neatstāj atsauces ārpus savas kodbāzes, tas ir izpildāms.Iespējams, vislabāk ir restartēt serveri. :-)