IPython में रीलोडिंग सबमॉड्यूल


363

वर्तमान में मैं एक अजगर परियोजना पर काम कर रहा हूं जिसमें उप मॉड्यूल शामिल हैं और सुन्न / डरावना है। Ipython का उपयोग इंटरैक्टिव कंसोल के रूप में किया जाता है। दुर्भाग्य से मैं वर्कफ़्लो से बहुत खुश नहीं हूं कि मैं अभी उपयोग कर रहा हूं, मैं कुछ सलाह की सराहना करूंगा।

IPython में, फ्रेमवर्क एक साधारण importकमांड द्वारा लोड किया जाता है । हालांकि, फ्रेमवर्क के किसी सबमॉडल में कोड को बदलना अक्सर आवश्यक होता है। इस बिंदु पर एक मॉडल पहले से ही लोड है और मैं इसके साथ बातचीत करने के लिए आईपीथॉन का उपयोग करता हूं।

अब, फ्रेमवर्क में कई मॉड्यूल होते हैं जो एक दूसरे पर निर्भर करते हैं, अर्थात जब फ्रेमवर्क को शुरू में लोड किया जाता है तो मुख्य मॉड्यूल सबडोड्यूल्स को आयात और कॉन्फ़िगर कर रहा है। कोड का परिवर्तन केवल तभी निष्पादित किया जाता है जब मॉड्यूल का उपयोग करके पुनः लोड किया जाता है reload(main_mod.sub_mod)। यह बोझिल है क्योंकि मुझे पूर्ण पथ का उपयोग करके सभी परिवर्तित मॉड्यूल को अलग-अलग लोड करने की आवश्यकता है। यह बहुत सुविधाजनक reload(main_module)होगा यदि सभी उप मॉड्यूलों को भी फिर से लोड किया जाएगा, लेकिन बिना खतना / घूंट फिर से लोड किए बिना।


क्या आप इस बारे में अधिक विस्तार से ध्यान देंगे However, it is often necessary to change code in one of the submodules of the framework.कि ऐसा क्यों है necessary to change code? धन्यवाद
खाएं

16
@eat: ढांचा लगातार विकसित हो रहा है, इसलिए कोड आधार में लगातार परिवर्तन होते रहते हैं।
एलैन

जवाबों:


531

IPython कुछ स्वत: पुनः लोडिंग जादू के साथ आता है :

%load_ext autoreload
%autoreload 2

यह नई लाइन को निष्पादित करने से पहले हर बार सभी परिवर्तित मॉड्यूल को फिर से लोड करेगा। यह काम करने का तरीका थोड़ा अलग है dreload। कुछ कैविएट लागू होते हैं, %autoreload?यह देखने के लिए टाइप करते हैं कि क्या गलत हो सकता है।


यदि आप इस सेटिंग को हमेशा सक्षम करना चाहते हैं, तो अपनी IPython कॉन्फ़िगरेशन फ़ाइल को संशोधित करें ~/.ipython/profile_default/ipython_config.py[1] और संलग्न करें:

c.InteractiveShellApp.extensions = ['autoreload']     
c.InteractiveShellApp.exec_lines = ['%autoreload 2']

नीचे एक टिप्पणी के माध्यम से @Kos को श्रेय।

[१] यदि आपके पास फाइल नहीं है ~/.ipython/profile_default/ipython_config.py, तो आपको ipython profile createपहले कॉल करना होगा । या फ़ाइल पर स्थित हो सकता है $IPYTHONDIR


63
मेरे पास c.InteractiveShellApp.extensions = ['autoreload']और c.InteractiveShellApp.exec_lines = ['%autoreload 2']में है ~/.ipython/profile_default/ipython_config.py
कोस

4
हालांकि, यह एक प्रदर्शन हिट हो सकता है, इसलिए सावधानी के साथ उपयोग करें।
asmeurer

3
पुनः लोड केवल तभी किया जाता है जब आप Enter को Ipython शेल में मारते हैं, और आमतौर पर ध्यान देने योग्य नहीं।
पी.वी.

3
यह बहुत अच्छा काम करता है जब पैकेज डिबगिंग करता है, इसलिए ड्रेलोड का उद्देश्य क्या है, ऐसा लगता है कि ड्रेपलोड बहुत आक्रामक और प्रिंट त्रुटि है जब कुछ पैकेज जैसे मैटप्लोटलिब लोड होते हैं।
दिलदार

3
यदि आप @Kos विधि का उपयोग करते हैं, तो सुनिश्चित करें कि c परिभाषित है: c = get_config ()
टिकॉन

27

IPython 0.12 में (और संभवतः पहले), आप इसका उपयोग कर सकते हैं:

%load_ext autoreload
%autoreload 2

यह अनिवार्य रूप से pv द्वारा उत्तर के समान है , सिवाय इसके कि नाम बदल दिया गया है और अब इसका उपयोग करके लोड किया गया है %load_ext


20

किसी कारण से, जब आप एक नोटबुक से दूसरे में कोड आयात करते हैं , तो न %autoreloadतो और न ही dreloadउस स्थिति के लिए काम करने लगते हैं । केवल सादा अजगर काम करता है:reload

reload(module)

के आधार पर [1]


10
पायथन 3.4+ में, आप इंपोर्टलिब मॉड्यूल में पुनः लोड कर सकते हैं। इस प्रश्न को देखें ।
प्रवीण

1
%autoreloadतकनीक के विपरीत, एक इंस्टेंस विधि को जोड़ने पर यह विधि काम करती है । इसके लिए समर्थन जोड़ने के लिए%autoreload एक खुली बग रिपोर्ट है
जोजफ

18

IPython dreload()सभी सबमॉड्यूल को पुन: लोड करने की पेशकश करता है। व्यक्तिगत रूप से, मैं %run()जादू कमांड का उपयोग करना पसंद करता हूं (हालांकि यह एक गहरी पुनः लोड नहीं करता है, जैसा कि जॉन साल्वेटियर ने टिप्पणियों में बताया है)।


11
मुझे लगता है कि (दुर्भाग्य से)% स्क्रिप्ट स्क्रिप्ट केवल उसी स्क्रिप्ट को पुनः लोड करता है जिसे आप कॉल कर रहे हैं, न कि इसे आयात करने वाले पैकेज। यदि आप अपने द्वारा बनाए जा रहे पैकेज को डीबग करने का प्रयास कर रहे हैं, तो यह एक दर्द हो सकता है।
जॉन साल्वेटियर

2
एनबी। dreloadहाल ही के आईपीथॉन (जैसे आईपीथॉन 6.0) को डीप लोड के द्वारा बदल दिया गया है ।
डैन मैकिनलेले

8

मॉड्यूल नाम importlibआंतरिक आयात करने के लिए उपयोग करने की अनुमति देते हैं। विशेष रूप से, यह कार्य प्रदान करता है importlib.reload():

import importlib
importlib.reload(my_module)

इसके विपरीत %autoreload, importlib.reload()मॉड्यूल में सेट किए गए वैश्विक चर भी रीसेट करें। ज्यादातर मामलों में, यह वही है जो आप चाहते हैं।

importlibकेवल पायथन 3.1 के बाद से उपलब्ध है। पुराने संस्करण के लिए, आपको मॉड्यूल का उपयोग करना होगा imp


केवल समाधान है कि मेरे लिए काम किया
gustavz

5

http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/

उन मैजिक फंक्शन को बार-बार टाइप करने से बचने के लिए, उन्हें ipython स्टार्टअप स्क्रिप्ट में रखा जा सकता है (इसका नाम .py प्रत्यय के अंतर्गत .ipython / profile_default / स्टार्टअप के साथ रखें। उस फ़ोल्डर के अंतर्गत सभी अजगर स्क्रिप्ट्स लेक्सिकल ऑर्डर के अनुसार लोड की जाएंगी)। निम्नलिखित की तरह दिखता है:

from IPython import get_ipython
ipython = get_ipython()

ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")

यदि आप अपनी स्क्रिप्ट %run script.pyको IPython REPL से उदाहरण के लिए चला रहे हैं तो यह भी काम करने लगता है
पैट्रिक सनन

3

इस बारे में कैसा है:

import inspect

# needs to be primed with an empty set for loaded
def recursively_reload_all_submodules(module, loaded=None):
    for name in dir(module):
        member = getattr(module, name)
        if inspect.ismodule(member) and member not in loaded:
            recursively_reload_all_submodules(member, loaded)
    loaded.add(module)
    reload(module)

import mymodule
recursively_reload_all_submodules(mymodule, set())

यह प्रभावी रूप से आपके द्वारा दिए गए मॉड्यूल और सबमॉड्यूल के पूरे पेड़ को फिर से लोड करना चाहिए। आप इस फ़ंक्शन को अपने .ipythonrc (मुझे लगता है) में डाल सकते हैं ताकि यह हर बार जब आप दुभाषिया शुरू करें तो लोड हो।


यह अच्छा लग रहा है, हालांकि, यह हो सकता है कि यह मॉड्यूल या मॉड्यूल के सदस्यों को कवर नहीं कर रहा है जो कि उपयोग कर रहे हैं from ... import ...या आयात किए गए हैं import ... as। टर्मिनल पर अंतःक्रियात्मक रूप से काम करने पर कम से कम मुझे अक्सर कुछ परेशानी होती है। मैं IPython में संग्रहित मैक्रो का उपयोग करने के लिए आगे बढ़ा हूं जो कि पूर्वनिर्धारित स्थिति में काम करना शुरू करने के लिए आवश्यक आयात और सेटअप करते हैं।
बर्नहार्ड

यह वास्तव में कवर करता है from ... import ...और import ... asजब तक आपके द्वारा आयात की गई चीज एक मॉड्यूल है। केवल एक चीज जो इसे कवर नहीं करती है वह एक पैकेज में मॉड्यूल है जो इसे __init__.pyफ़ाइल से लोड नहीं किया गया था । पैकेज के लिए, आप संभवतः जाँच सकते हैं कि मॉड्यूल की __path__विशेषता एक निर्देशिका है या नहीं। यदि यह है, तो इसे पीछे छोड़ दें और आपके द्वारा खोजे जा सकने वाले सभी मॉड्यूल को पुन: आयात करें। मैंने इस भाग को नहीं लिखा है क्योंकि लेखक ने पैकेजों के लिए समाधान नहीं पूछा है।
YH वोंग

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

इसके अलावा, आप pkgutilएक पैकेज में सभी सबमॉड्यूल प्राप्त करने के लिए उपयोग कर सकते हैं , भले ही पैकेज टॉप मॉड्यूल में सबमॉड्यूल आयात न करे। stackoverflow.com/a/1707786/1243926
osa

आपको यह भी करना है: मॉड्यूल के लिएsys.modules:
aoeu256


1

पुन: लोड करने के लिए मेरा मानक अभ्यास दोनों तरीकों को पहले उद्घाटन के बाद संयोजित करना है IPython:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

ऐसा करने से पहले लोड हो रहा है मॉड्यूल उन्हें लोड नहीं किया जाएगा, भले ही एक मैनुअल के साथ reload(module_name)। मैं अभी भी, बहुत कम ही, क्लास के तरीकों के साथ अक्षम्य समस्याओं को पुनः लोड करता हूं जो मैंने अभी तक नहीं देखा है।


1

ध्यान दें कि उपर्युक्त autoreloadकेवल IntelliJ में काम करता है यदि आप मैन्युअल रूप से परिवर्तित फ़ाइल (जैसे ctrl + s या cmd + s का उपयोग करके) को सहेजते हैं। यह ऑटो-सेविंग के साथ काम नहीं करता है।


मैं इस बात की पुष्टि करता हूं कि Pyharm के लिए भी यही मामला है।
tsando

0

एनाकोंडा पर जुपिटर नोटबुक पर, यह कर:

%load_ext autoreload
%autoreload 2

संदेश का उत्पादन किया:

ऑटोरेलोड एक्सटेंशन पहले से लोड है। इसे पुनः लोड करने के लिए, उपयोग करें: %reload_ext autoreload

ऐसा लगता है कि यह करना बेहतर है:

%reload_ext autoreload
%autoreload 2

संस्करण जानकारी:

नोटबुक सर्वर का संस्करण 5.0.0 है और चल रहा है: पायथन 3.6.2 | एनाकोंडा, इंक (डिफ़ॉल्ट, 20 सितंबर 2017, 13:35:58) [MSC v.1900 32 बिट (इंटेल)]


0

किसी भी उप-विषय को इसके द्वारा पुनः लोड नहीं किया जाएगा, मेरा मानना ​​है कि आपको इसके लिए IPython के डीप लोड का उपयोग करना होगा।

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