Περισσότερα
Πώς μπορώ να ξεφορτώσω (επαναφορτώσω) μια ενότητα;
Έχω έναν διακομιστή Python που λειτουργεί για μεγάλο χρονικό διάστημα και θα ήθελα να μπορώ να αναβαθμίσω μια υπηρεσία χωρίς να επανεκκινήσω τον διακομιστή. Ποιος είναι ο καλύτερος τρόπος για να το κάνω αυτό;
if foo.py has changed:
unimport foo <-- How do I do this?
import foo
myfoo = foo.Foo()
756
3
Μπορείτε να επαναφορτώσετε μια ενότητα όταν έχει ήδη εισαχθεί χρησιμοποιώντας την ενσωματωμένη συνάρτηση
reload
:Στην Python 3, η
reload
μεταφέρθηκε στην ενότηταimp
. Στην έκδοση 3.4, τοimp
καταργήθηκε για χάρη τουimportlib
, και τοreload
προστέθηκε στο τελευταίο. Όταν στοχεύετε στο 3 ή μεταγενέστερο, είτε αναφερθείτε στο κατάλληλο module όταν καλείτε τοreload
είτε εισάγετε το.Νομίζω ότι αυτό είναι που θέλετε. Οι διακομιστές ιστού όπως ο διακομιστής ανάπτυξης του Django'το χρησιμοποιούν αυτό, ώστε να μπορείτε να δείτε τα αποτελέσματα των αλλαγών στον κώδικά σας χωρίς να επανεκκινήσετε την ίδια τη διαδικασία του διακομιστή.
Για να παραθέσω ένα απόσπασμα από τα έγγραφα:
Ο κώδικας των ενοτήτων Python μεταγλωττίζεται εκ νέου και
Όπως σημειώσατε στην ερώτησή σας, θα πρέπει να ανακατασκευάσετε τα αντικείμενα
Foo
αν η κλάσηFoo
βρίσκεται στην ενότηταfoo
.Μπορεί να είναι ιδιαίτερα δύσκολο να διαγράψετε μια ενότητα αν δεν είναι καθαρή Python.
Εδώ είναι μερικές πληροφορίες από το: Πώς μπορώ πραγματικά να διαγράψω μια εισαγόμενη ενότητα;
>,
>,
reload(module)
, αλλά μόνο αν είναι εντελώς αυτόνομο. Αν οτιδήποτε άλλο έχει αναφορά στο module (ή σε οποιοδήποτε αντικείμενο που ανήκει στο module), τότε θα λάβετε λεπτά και περίεργα σφάλματα που προκαλούνται από τον παλιό κώδικα που παραμένει εκεί περισσότερο από όσο περιμένατε, και πράγματα όπως τοisinstance
που δεν λειτουργεί σε διαφορετικές εκδόσεις του ίδιου κώδικα.Αν έχετε μονόδρομες εξαρτήσεις, πρέπει επίσης να επαναφορτώσετε όλες τις ενότητες που εξαρτώνται από την επαναφορτωμένη ενότητα για να απαλλαγείτε από όλες τις αναφορές στον παλιό κώδικα. Και στη συνέχεια να επαναφορτώσετε αναδρομικά τα modules που εξαρτώνται από τα επαναφορτωμένα modules.
Αν έχετε κυκλικές εξαρτήσεις, κάτι που είναι πολύ συνηθισμένο για παράδειγμα όταν έχετε να κάνετε με την επαναφόρτωση ενός πακέτου, πρέπει να ξεφορτώσετε όλα τα modules της ομάδας με μία κίνηση. Δεν μπορείτε να το κάνετε αυτό με την
reload()
επειδή θα επαναφέρει κάθε ενότητα πριν ανανεωθούν οι εξαρτήσεις της, επιτρέποντας σε παλιές αναφορές να εισχωρήσουν σε νέες ενότητες.Ο μόνος τρόπος για να το κάνετε σε αυτή την περίπτωση είναι να χακάρετε το
sys.modules
, το οποίο είναι κάπως μη υποστηριζόμενο. Θα πρέπει να ψάξετε και να διαγράψετε κάθε καταχώρηση τουsys.modules
που θέλετε να επαναφορτωθεί στην επόμενη εισαγωγή, και επίσης να διαγράψετε καταχωρήσεις των οποίων οι τιμές είναιNone
για να αντιμετωπίσετε ένα θέμα υλοποίησης που έχει να κάνει με την προσωρινή αποθήκευση αποτυχημένων σχετικών εισαγωγών. Δεν είναι και τόσο ωραίο, αλλά εφόσον έχετε ένα πλήρως αυτοτελές σύνολο εξαρτήσεων που δεν αφήνει αναφορές εκτός της βάσης κωδικών του, είναι λειτουργικό.Πιθανότατα είναι καλύτερο να επανεκκινήσετε τον διακομιστή :-)