2010-03-28 11 views
21

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

>>> from project.model.user import * 
>>> reload(user) 

लेकिन मैं प्राप्त करते हैं:

>>>NameError: name 'user' is not defined 

पूरे उपयोगकर्ता वर्ग फिर से लोड करने के लिए उचित तरीका क्या है? क्या ऐसा करने का कोई बेहतर तरीका है, शायद डीबगिंग के दौरान ऑटो-अपडेटिंग?

धन्यवाद।

उत्तर

29

के रूप में पूछा, सबसे अच्छा तुम कर सकते हो

>>> from project.models.user import * 
>>> import project # get module reference for reload 
>>> reload(project.models.user) # reload step 1 
>>> from project.models.user import * # reload step 2 

बेहतर और क्लीनर होगा यदि आप बल्कि import * कर (जो यह करने के लिए सही तरीके से लगभग कभी नहीं है) की तुलना में, सीधे उपयोगकर्ता मॉड्यूल का इस्तेमाल किया है । तो यह केवल

>>> from project.models import user 
>>> reload(user) 

यह वही होगा जो आप चाहते हैं। लेकिन, यह बहुत अच्छा नहीं है। यदि आपको वास्तव में मॉड्यूल को फिर से लोड करने की ज़रूरत है, तो मुझे पूछना होगा: क्यों?

मेरा संदेह (समान प्रश्न पूछने वाले लोगों के साथ पिछले अनुभव का बैक अप) यह है कि आप अपने मॉड्यूल का परीक्षण कर रहे हैं। मॉड्यूल का परीक्षण करने के कई तरीके हैं, और इंटरैक्टिव दुभाषिया में हाथ से ऐसा करना सबसे खराब तरीकों में से एक है। अपने सत्रों में से किसी एक को फ़ाइल में सहेजें और त्वरित सुधार के लिए doctest का उपयोग करें। वैकल्पिक रूप से, इसे एक प्रोग्राम के रूप में लिखें और python -i का उपयोग करें। हालांकि, वास्तव में एकमात्र महान समाधान unittest मॉड्यूल का उपयोग कर रहा है।

यदि ऐसा नहीं है, तो उम्मीद है कि यह कुछ बेहतर है, बदतर नहीं। वास्तव में reload का कोई अच्छा उपयोग नहीं है (वास्तव में, यह 3.x में हटा दिया गया है)। यह प्रभावी ढंग से काम नहीं करता है - आप मॉड्यूल को फिर से लोड कर सकते हैं लेकिन पिछले संस्करणों से बचे हुए छोड़ सकते हैं। यह सभी प्रकार के मॉड्यूल पर भी काम नहीं करता है - फिर से लोड होने पर एक्सटेंशन मॉड्यूल ठीक से फिर से लोड नहीं होंगे, या कभी-कभी भयानक तोड़ देंगे।

इंटरैक्टिव दुभाषिया में इसका उपयोग करने का संदर्भ आपके द्वारा किए जा रहे कार्यों के अनुसार बहुत सारे विकल्प नहीं छोड़ता है, और वास्तविकतम समाधान क्या होगा।इसके बाहर, कभी-कभी लोग प्लगइन इत्यादि को लागू करने के लिए reload() का उपयोग करते थे। यह सबसे अच्छा खतरनाक है, और अक्सर exec (आह बुराई क्षेत्र जिसे हम स्वयं पाते हैं) या एक पृथक प्रक्रिया का उपयोग करके अलग-अलग किया जा सकता है।

+0

+1: वास्तव में पुनः लोड करने का कोई अच्छा उपयोग नहीं है। –

+0

मैं इस प्रश्न को खोजने के लिए क्या कर रहा हूं, क्या मैं JSON से आयातित डेटा संरचना का पता लगाने के लिए कंसोल का उपयोग कर रहा हूं। मैं अपने टेक्स्ट एडिटर में कुछ फ़ंक्शंस रखने के लिए "रीलोड" का उपयोग करना चाहता हूं जो विभिन्न तरीकों से संरचना को पार करता है, उन्हें संपादित करता है, फिर कंसोल से बाहर निकले बिना उन्हें फिर से चालू करता है। फिर भी, यदि पाइथन इसे स्पष्ट रूप से समर्थन नहीं दे सकता है, तो "बचे हुए" को हटाने में असमर्थता के कारणों के लिए, मुझे लगता है कि मुझे ऐसा करना गलत होना चाहिए; उत्तर के लिए +1 +1 जो मुझे वैसे भी करने देता है, हालांकि। –

+0

+1 मुझे यह दिखाने के लिए कि मुझे वास्तव में वास्तव में, ठीक ट्यूनिंग के लिए भी हाथ से दुभाषिया में चीजों को करने के बजाय परीक्षण लिखना चाहिए। यह भविष्य के गैर-रिग्रेशन परीक्षण के लिए भी उपयोगी होगा। –

4

दुर्भाग्य से आप का उपयोग करने के लिए मिला है:

>>> from project.model import user 
>>> reload(user) 

मैं कुछ जो स्वचालित रूप से इंटरैक्टिव प्रॉम्प्ट पर मॉड्यूल पुनः लोड होगा की मेरे सिर के ऊपर से पता नहीं है ... लेकिन मैं किसी भी कारण नहीं दिख रहा है एक मौजूद नहीं होना चाहिए (वास्तव में, यह भी लागू करने के लिए मुश्किल नहीं होगा, या तो ...)

अब, आप कुछ इस तरह कर सकता है:

from types import ModuleType 
import sys 
_reload_builtin = reload 
def reload(thing): 
    if isinstance(thing, ModuleType): 
     _reload_builtin(thing) 
    elif hasattr(thing, '__module__') and thing.__module__: 
     module = sys.modules[thing.__module__] 
     _reload_builtin(module) 
    else: 
     raise TypeError, "reload() argument must be a module or have an __module__" 
4

आप एक प्रभावी तरीके से पुनः लोड() का उपयोग नहीं कर सकते हैं।

पायथन पहले आयातित मॉड्यूल के पुनः लोड या अनलोडिंग के लिए प्रभावी समर्थन प्रदान नहीं करता है; मॉड्यूल संदर्भ मॉड्यूल को पुनः लोड करने के लिए अव्यवहारिक बनाता है क्योंकि आपके प्रोग्राम के कई स्थानों पर संदर्भ मौजूद हो सकते हैं।

पायथन 3 ने पूरी तरह से रीलोड() सुविधा हटा दी है।

+1

यह मॉड्यूल संदर्भ नहीं है जो ऐसा करता है: पुनः लोड() वास्तव में मॉड्यूल ऑब्जेक्ट को म्यूट करता है। यह मॉड्यूल के अंदर कार्यों और कक्षाओं के संदर्भ है जो चीजों को तोड़ते हैं (विशेष रूप से, foo आयात * से उत्पन्न संदर्भ)। –

+0

हां मैं सहमत हूं, और आपके पास अन्य प्रोग्राम मॉड्यूल हो सकते हैं जिन्होंने मॉड्यूल को आयात किया है जिसे आप अनलोड करना चाहते हैं()। – systempuntoout

0

आप twisted.python.rebuild.rebuild भी आजमा सकते हैं।

%load_ext autoreload 
%autoreload 2 

कहाँ %autoreload 2 पुनः लोड "। सभी मॉड्यूल द्वारा लिखा गया अजगर कोड को क्रियान्वित करने से पहले हर बार (% aimport से बाहर रखा गया उनके अलावा)":

1

python3 के लिए, पुनः लोड मॉड्यूल छोटा सा भूत के लिए ले जाया गया है। आप imp.reload() का उपयोग कर सकते हैं। आप this post देख सकते हैं।

>>> import imp 
>>> import project # get module reference for reload 
>>> imp.reload(project.models.user) # reload step 1 
>>> from project.models.user import * # reload step 2 
संबंधित मुद्दे

 संबंधित मुद्दे