2009-12-24 10 views
5

यदि मेरे पास कोई प्रोग्राम है जहां stdout रीडायरेक्ट किया गया है, तो मेरा पीडीबी सभी को पुनर्निर्देशन के लिए संकेत देता है, क्योंकि लाइब्रेरी को stdout पर लिखने के लिए लिखा गया था।पायथन पीडीबी flakiness re/stdout से निपटने के लिए सबसे अच्छा तरीका है?

अक्सर यह समस्या सूक्ष्म है, जिससे मुझे लगता है कि यह वास्तव में इनपुट के लिए इंतजार कर रहा है जब एक कार्यक्रम लटक रहा है।

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

उत्तर

2

समस्या है कि यहाँ PDB Cmd वर्ग का उपयोग करता है, जहां डिफ़ॉल्ट रूप से:

use_rawinput = 1 

इसका मतलब है कि कंसोल से पढ़ने के लिए sys.stdout.readline() की बजाय डिफ़ॉल्ट रूप से raw_input() विधि का उपयोग करेगा। ऐसा इसलिए किया जाता है क्योंकि raw_input() इतिहास का समर्थन करता है (केवल readline मॉड्यूल लोड किया गया है) और अन्य उपयोगी बिट्स। केवल मुद्दा यह है कि raw_input() पुनर्निर्देशन का समर्थन नहीं करता है, इसलिए यदि आप एक स्क्रिप्ट है:

#!/usr/bin/python 
name=raw_input("Enter your name: ") 

और यह

> python test.py 
Enter your name: Alex 

चलाने लेकिन, यदि आप इसे उत्पादन पुनर्निर्देशन यह अटक जाएगा के साथ चलाने के

> python test.py | tee log 

यह वही है जो पीडीबी उपयोग करता है और यह भी अटक गया है। जैसा कि मैंने बताया है sys.stdin.readline() पुनर्निर्देशन का समर्थन करता है और यदि आप उपरोक्त स्क्रिप्ट को readline() का उपयोग करके पुनः लिखते हैं तो इसे काम करना चाहिए।

मूल मुद्दे पर वापस तुम सब करने की जरूरत है Cmd बताने के लिए raw_input() का उपयोग नहीं करने के लिए है:

Cmd.use_rawinput = 0 

या

pdb = pdb.Pdb() 
pdb.use_rawinput=0 
pdb.set_trace() 
2

यदि आप कोड में पीडीबी का आविष्कार कर रहे हैं, तो आप अपने स्वयं के stdout को कन्स्ट्रक्टर में पास कर सकते हैं। sys.__stdout__ एक अच्छा विकल्प हो सकता है।

यदि आप कमांड लाइन से पीडीबी का आविष्कार कर रहे हैं, तो आप main() फ़ंक्शन को अपने स्वयं के sane_pdb.py में pdb.py से कॉपी कर सकते हैं।

pdb = Pdb(stdout=sys.__stdout__) 

तो फिर तुम pdb.py. के बजाय sane_pdb.py आह्वान कर सकते हैं: तो फिर करने के लिए PDB() प्रारंभ बदल यह भयानक नहीं है कि आपको उनमें से किसी एक को बदलने के लिए अपनी लाइन में 40 लाइनों की प्रतिलिपि बनाना होगा, लेकिन यह एक विकल्प है।

4

इस उत्तर सिर्फ नेड के पूरक के लिए किया जाता है, एक तरीके से pdb.py main() समारोह है जो 40 लाइनों को कॉपी की आवश्यकता नहीं है लपेटकर के एक तरीके के रूप में सिर्फ उन में से एक को बदलने के लिए:

# sane_pdb.py: launch Pdb with stdout on original 
import sys, pdb 
def fixed_pdb(Pdb=pdb.Pdb): 
    '''make Pdb() tied to original stdout''' 
    return Pdb(stdout=sys.__stdout__) 

if __name__ == '__main__': 
    pdb.Pdb = fixed_pdb 
    pdb.main() 

मैं डॉन 'टी पता है कि यह वास्तव में प्रश्नकर्ता की समस्या के लिए काम करता है, लेकिन यह क्या नेड वर्णित है ...