2012-01-07 13 views
5

वर्तमान में, मेरे पास एक ऐसा एप्लिकेशन है जो कमांड लाइन इंटरफ़ेस के लिए cmd.Cmd मॉड्यूल का उपयोग करता है, टैब-पूर्णता पूरी तरह से काम करता है।cmd.Cmd में पायथन रीडलाइन टैब-समापन, जब sys.stdout को

अब, मैं sys.stdout को बदलने के लिए किसी अन्य वस्तु के साथ, टुकड़ा सिद्धांत रूप में पूरी तरह से पारदर्शी होना चाहिए के बाद, के रूप में हर मिल/सेट आपरेशन करना चाहते हैं (आदेश क्या लिखा जा रहा है पर कब्जा करने में उदाहरण के लिए,।)

STD ऑब्जेक्ट कोपर रीडायरेक्ट किया गया है।

class Std(object): 
    def __getattribute__(self, name): 
     if name in ('__getattribute__', '__setattr__'): 
      return object.__getattribute__(self, name) 
     else: 
      return getattr(sys.__stdout__, name) 

    def __setattr__(self, name, value): 
     setattr(sys.__stdout__, name, value) 

sys.stdout = Std() 

उदाहरण के लिए, sys.stdout.fileno() अभी भी प्रिंट होगा 1. हालांकि, Cmd.cmd की ReadLine टैब-पूरा होने नहीं रह गया अब काम करता है ...

ठीक है, फ़ाइल से विरासत करते हैं। (Stdout एक फ़ाइल वस्तु है।)

class Std(file): 
    def __init__(self): 
     pass 
    def __getattribute__(self, name): 
     if name in ('__getattribute__', '__setattr__'): 
      return object.__getattribute__(self, name) 
     else: 
      return getattr(sys.__stdout__, name) 

    def __setattr__(self, name, value): 
     setattr(sys.__stdout__, name, value) 

sys.stdout = Std() 

और अब मैं:

Traceback (most recent call last): 
    File "./shell.py", line 61, in <module> 
    print '#1' 
ValueError: I/O operation on closed file 

हालांकि, निम्नलिखित धारणा में विफल नहीं हुआ:

assert not sys.stdout.closed 

किसी तरह, मुझे लगता है, अजगर है कुछ overoptimizing, और Std.write को छोड़कर।

मुझे रीडलाइन समर्थन को खोए बिना stdout को प्रतिस्थापित करने के लिए क्या करना चाहिए ...?

जोनाथन

-edit-

मैं भी sys.stdin को बदलने के लिए कोशिश कर रहा हूँ। इसे cmd.Cmd पर पास करना काम नहीं करता है, क्योंकि raw_input को रीडलाइन समर्थन के लिए उपयोग किया जाता है और पायथन का raw_input फ़ाइल डिस्क्रिप्टर को स्वीकार नहीं करता है। यह sys.stdin को जो भी pty सौंपा गया है वापस आ जाता है।

जब मैं एक नया पीटीआई (os.openpty() के माध्यम से) बना देता हूं, और इस जोड़ी sys.stdin/out को असाइन करता हूं, उस पीटीआई कार्यों के माध्यम से स्वत: पूर्णता को रेखांकित करता है, लेकिन फिर, जब प्रॉक्सी ऑब्जेक्ट में लपेटा जाता है, तो यह काम करता है , लेकिन स्वत: पूर्णता के बिना।

ReadLine के स्रोत को समझने की कोशिश कर रहा है, लेकिन यह आसान नहीं है: http://svn.python.org/projects/python/branches/release25-maint/Modules/readline.c

उत्तर

1

मैं नहीं जानता कि ठीक क्यों sys.stdout की जगह काम नहीं करता है, लेकिन किसी भी मामले में आप उत्तीर्ण करके तत्काल समस्याओं को ठीक कर सकते हैं cmd.Cmd के लिए निर्माता के लिए अपनी स्वयं की फ़ाइल ऑब्जेक्ट।

import sys, cmd 

class Std(object): 
    def __getattribute__(self, name): 
     if name in ('__getattribute__', '__setattr__'): 
      return object.__getattribute__(self, name) 
     else: 
      return getattr(sys.__stdout__, name) 

    def __setattr__(self, name, value): 
     setattr(sys.__stdout__, name, value) 

class HelloWorld(cmd.Cmd): 
    FRIENDS = [ 'Alice', 'Adam', 'Barbara', 'Bob' ] 

    def do_greet(self, person): 
     "Greet the person" 
     if person and person in self.FRIENDS: 
      greeting = 'hi, %s!' % person 
     elif person: 
      greeting = "hello, " + person 
     else: 
      greeting = 'hello' 
     print greeting 

    def complete_greet(self, text, line, begidx, endidx): 
     if not text: 
      completions = self.FRIENDS[:] 
     else: 
      completions = [f for f in self.FRIENDS 
          if f.startswith(text)] 
     return completions 

    def do_EOF(self, line): 
     return True 

if __name__ == '__main__': 

    HelloWorld(stdout=Std()).cmdloop() 

अपने उद्देश्यों के लिए, यह काम करने के एक बेहतर तरीका है, क्योंकि यह सुनिश्चित आप केवल हो जाएगा:

यहाँ एक उदाहरण स्क्रिप्ट (आंशिक रूप से PyMOTW से उधार) है, उस टैब-पूरा होने को दर्शाता है आउटपुट को कैप्चर करना जो आपके Cmd इंस्टेंस का उत्पादन करता है।

ध्यान दें कि आपके द्वारा पास की जाने वाली फ़ाइल ऑब्जेक्ट Cmd उदाहरण पर stdout विशेषता के रूप में भी उपलब्ध है।

+0

धन्यवाद, लेकिन यह वास्तव में मदद नहीं करता है। 'Cmd.Cmd .__ init__' में चेक किया गया है कि क्या स्टडआउट कोई नहीं है, अगर ऐसा है, तो sys.stdout में फॉलबैक है। तो, यह बिल्कुल वही है, जैसा कि sys.stdin/out के रूप में जाना जाता है। –

+0

@ जोनाथन स्लेंडर। मैंने पहले परीक्षण किए बिना समाधान की पेशकश नहीं की होगी। मेरे लिए, यह टैब-पूर्णता के साथ समस्या को हल करता है। मैंने 'stdin' के लिए कोई परीक्षण नहीं किया, क्योंकि यह आपके मूल प्रश्न का हिस्सा नहीं था - लेकिन मैंने [cmd.Cmd] (http://docs.python.org/library/cmd.html के लिए प्रलेखन पढ़ा था # cmd.Cmd) और [use_rawinput] (http://docs.python.org/library/cmd.html#cmd.Cmd.use_rawinput), जो उस समस्या के बारे में प्रासंगिक जानकारी प्रतीत होता है। – ekhumoro

+0

@ जोनाथन स्लेंडर। मैंने अपने उत्तर को स्क्रिप्ट के साथ अपडेट किया है जिसका उपयोग मैंने परीक्षण के लिए किया था। – ekhumoro

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