इंटरएक्टिव करते समय अजगर में एक मॉड्यूल को फिर से खोलें


381

मुझे पता है कि यह किया जा सकता है, लेकिन मुझे याद नहीं है कि कैसे।

आप अजगर में एक मॉड्यूल को कैसे पुनः प्राप्त कर सकते हैं? परिदृश्य निम्नानुसार है: मैं एक मॉड्यूल को अंतःक्रियात्मक रूप से आयात करता हूं और इसके साथ टिंकर करता हूं, लेकिन फिर मुझे एक त्रुटि का सामना करना पड़ता है। मैं .py फ़ाइल में त्रुटि को ठीक करता हूं और फिर मैं अजगर को छोड़ने के बिना निश्चित मॉड्यूल को फिर से जोड़ना चाहता हूं। मैं यह कैसे कर सकता हूं ?



जवाबों:


367

यह काम करना चाहिए:

reload(my.module)

से अजगर डॉक्स

पहले से आयात किए गए मॉड्यूल को पुनः लोड करें। तर्क एक मॉड्यूल ऑब्जेक्ट होना चाहिए, इसलिए इसे पहले सफलतापूर्वक आयात किया जाना चाहिए। यह उपयोगी है अगर आपने बाहरी संपादक का उपयोग करके मॉड्यूल स्रोत फ़ाइल को संपादित किया है और पायथन दुभाषिया को छोड़ने के बिना नए संस्करण को आज़माना चाहते हैं।

यदि पायथन 3.4 रन और ऊपर, करो import importlib, तो करो importlib.reload(nameOfModule)

इस विधि का उपयोग करने के कैविएट को न भूलें:

  • जब एक मॉड्यूल पुनः लोड किया जाता है, तो इसका शब्दकोश (मॉड्यूल के वैश्विक चर युक्त) को बरकरार रखा जाता है। नामों की पुनर्निर्धारण पुरानी परिभाषाओं को पार कर जाएगी, इसलिए यह आमतौर पर कोई समस्या नहीं है, लेकिन अगर मॉड्यूल के नए संस्करण में एक नाम को परिभाषित नहीं किया जाता है जो पुराने संस्करण द्वारा परिभाषित किया गया था, तो पुरानी परिभाषा को हटाया नहीं जाता है।

  • यदि कोई मॉड्यूल किसी अन्य मॉड्यूल का उपयोग करके वस्तुओं का आयात करता है, तो दूसरे मॉड्यूल के लिए from ... import ...कॉल करने से आयात की गई वस्तुओं को reload()फिर से परिभाषित नहीं करता है - इसके चारों ओर एक तरीका fromबयान को फिर से निष्पादित करना है, दूसरा उपयोग करना है importऔर module.*name*इसके बजाय योग्य नामों ( ) का उपयोग करना है।

  • यदि कोई मॉड्यूल किसी वर्ग के उदाहरणों को त्वरित करता है, तो वर्ग को परिभाषित करने वाले मॉड्यूल को फिर से लोड करना, उदाहरणों की विधि परिभाषाओं को प्रभावित नहीं करता है - वे पुरानी वर्ग की परिभाषा का उपयोग करना जारी रखते हैं। व्युत्पन्न वर्गों के लिए भी यही सच है।


26
अगर मैं अपने मॉड्यूल का उपयोग कर लोड करता हूं from filename import *। पुनः लोड कैसे करें?
पीटर झू

@PeterZhu "मॉड आयात fcn" मामले के लिए, मॉड्यूल ऑब्जेक्ट को नाम स्थान में नहीं जोड़ा गया है। इसलिए आपको मॉड्यूल को स्पष्ट रूप से आयात करने की आवश्यकता है, इसलिए आप बाद में इसे फिर से लोड कर सकते हैं। import foo; from foo import bar; reload(foo)
टेड

मैंने पुनः लोड करने की कोशिश की, साथ ही ऑटोरैलोएड जादू, और मुझे त्रुटि संदेश के स्टैक में परिलक्षित मेरा कोड परिवर्तन दिखाई देता है, लेकिन त्रुटि स्वयं अभी भी बासी कोड से दूर प्रतीत होती है (उदाहरण के लिए, त्रुटि की रेखा ठीक उसी पर है पहले की तरह लाइन, जिसे मैंने एक टिप्पणी में बदल दिया है, और एक टिप्पणी स्पष्ट रूप से त्रुटियों का कारण नहीं बन सकती है)। मेरा मॉड्यूल जुपिटर एक्सटेंशन के रूप में लोड किया गया है, क्या किसी को पता चल सकता है कि इसके लिए अलग से काम की आवश्यकता है? धन्यवाद!
यिफानवु

1
यदि आप "नाम के रूप में आयात मॉड" के बाद अपने फ़ंक्शन को आयात करते हैं, तो आपको निम्नानुसार करने की आवश्यकता है: 'import importibib importlib.reload (नाम)'
Noe

यह विधि पुनः लोड किए गए मॉड्यूल के अन्य मॉड्यूल के संदर्भ को ओवरराइड नहीं कर सकती है। इसके समाधान के लिए stackoverflow.com/a/61617169/2642356 देखें ।
EZLearner

287

अजगर 3 में, reloadअब एक निर्मित फ़ंक्शन नहीं है।

यदि आप अजगर 3.4+ का उपयोग कर रहे हैं, तो आपको इसके बजाय पुस्तकालय reloadसे उपयोग करना चाहिए importlib:

import importlib
importlib.reload(some_module)

यदि आप अजगर 3.2 या 3.3 का उपयोग कर रहे हैं तो आपको चाहिए:

import imp  
imp.reload(module)  

बजाय। Http://docs.python.org/3.0/library/imp.html#imp.reload देखें

यदि आप उपयोग कर रहे हैं ipython, तो निश्चित रूप से autoreloadएक्सटेंशन का उपयोग करने पर विचार करें:

%load_ext autoreload
%autoreload 2

हालाँकि बहुत सारे पायथन कोड पायथन 2 में लिखे गए हैं, लेकिन पायथन 3 हर दिन अधिक व्यवहार्य होता जा रहा है। पारितोषिक के लिए धन्यवाद!
एरोन जॉनसन

40
imp.reloadपायथन 3.4 के बाद से पदावनत किया गया है, इसके बजाय importlib.reloadफ़ंक्शन का उपयोग करें ।
jfs

1
@ और धन्यवाद! मैंने% ऑटोरैलोएड का उपयोग किया, यह अद्भुत है, मेरी पहले से बनाई गई वस्तुओं को स्वचालित रूप से वर्ग विधियों के सही कार्यान्वयन के बिना उन्हें फिर से बनाना है
jeanmi

4
मैं थोड़ी देर हो चुकी हूँ, लेकिन मैं यह काम करता है, तो क्या आप फिर से लोड करने की आवश्यकता है एक समारोह या मॉड्यूल के भीतर से वर्ग है नहीं लगता है: यदि मेरी आयात बयान था from mymodule import myfunc, तो importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)सब एक NameError दे।
पफ

@ पफ एक समारोह को फिर से आयात करने के लिए मेरा जवाब नीचे देखें
jss367

46

दरअसल, पायथन 3 में मॉड्यूल impको चिह्नित के रूप में चिह्नित किया गया है। खैर, कम से कम यह 3.4 के लिए सच है।

इसके बजाय मॉड्यूल reloadसे फ़ंक्शन का importlibउपयोग किया जाना चाहिए:

https://docs.python.org/3/library/importlib.html#importlib.reload

लेकिन ध्यान रहे कि इस लाइब्रेरी में पिछले दो छोटे संस्करणों के साथ कुछ एपीआई-परिवर्तन थे।


5

यदि आप किसी विशिष्ट फ़ंक्शन या वर्ग को मॉड्यूल से आयात करना चाहते हैं, तो आप ऐसा कर सकते हैं:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

0

यद्यपि प्रदान किए गए उत्तर एक विशिष्ट मॉड्यूल के लिए काम करते हैं, वे सबमॉड्यूल को फिर से लोड नहीं करेंगे, जैसा कि इस उत्तर में दिया गया है :

यदि कोई मॉड्यूल किसी अन्य मॉड्यूल का उपयोग करके वस्तुओं को आयात करता है, तो दूसरे मॉड्यूल के लिए from ... import ...कॉल करने से आयात की गई वस्तुओं को reload()फिर से परिभाषित नहीं करता है - इसके चारों ओर एक तरीका बयान से फिर से निष्पादित करना है, दूसरा इसके बजाय उपयोग importऔर योग्य नामों ( module.*name*) का उपयोग करना है।

हालांकि, अगर __all__सार्वजनिक एपीआई को परिभाषित करने के लिए चर का उपयोग किया जाता है, तो सभी सार्वजनिक रूप से उपलब्ध मॉड्यूल को स्वचालित रूप से पुनः लोड करना संभव है:

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

पिछले उत्तर में दिए गए विवरण हालांकि अभी भी मान्य हैं। विशेष रूप से, एक सबमॉड्यूल को संशोधित करना जो सार्वजनिक एपीआई का हिस्सा नहीं है जैसा कि __all__चर द्वारा वर्णित है, इस फ़ंक्शन का उपयोग करके पुनः लोड से प्रभावित नहीं होगा। इसी तरह, एक सबमॉड्यूल के एक तत्व को हटाने पर एक पुनः लोड नहीं होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.