2012-01-07 8 views
5

Şu anda, komut satırı arabirimi için cmd.Cmd modülünü kullanan bir uygulamam var, tab tamamlama mükemmel çalışıyor.Sys.stdout değiştirildikten sonra, cmd.Cmd Python readline sekmesi tamamlandı,

Şimdi, başka bir nesneyle, sys.stdout değiştirmek istiyorum (yazılırken ne yakalamak için, Örneğin.)

pasajı teoride tamamen şeffaf olmalıdır takiben, her/set işlemi için olsun Std nesnesi, sys.__stdout__ etkinliğine yeniden yönlendirilir.

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() 

Örneğin, sys.stdout.fileno() hala

Tamam ... 1. Ancak Cmd.cmd ait taleb sekme tamamlama artık şimdi çalışır yazdırmak en dosyadan devralan izin verir.

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() 

(. Stdout'u bir dosya nesnesidir) Ve şimdi olsun:

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

Ancak, aşağıdaki onaylama işlemi başarısız değildir: Her nasılsa

assert not sys.stdout.closed 

, sanırım, Python Bir şeyi aşırı hızlandırmak ve Std.write'yi atlamak.

Okunak desteğini kaybetmeden stdout'u değiştirmek için ne yapmalıyım? Ayrıca sys.stdin yerine çalışıyorum

-edit-

Jonathan. cmd.Cmd dosyasına aktarma, raw_input okuma desteği için kullanıldığından ve Python raw_input bir dosya tanıtıcısını kabul etmediğinden çalışmaz. Sys.stdin'e ne olursa olsun pty atanır.

Yeni bir pty (os.openpty() aracılığıyla) oluşturduğumda ve bu çifti sys.stdin/out öğesine atadığımda, bu pty üzerinden otomatik tamamlama otomatik olarak tamamlanır, ancak bir proxy nesnesine sarıldığında yeniden çalışır. ama otomatik tamamlama olmadan.

taleb kaynağını anlamaya çalışıyorum, ama kolay değildir: sys.stdout yerine çalışmıyor tam olarak bu yüzden http://svn.python.org/projects/python/branches/release25-maint/Modules/readline.c

cevap

1

Bilmiyorum, ama her durumda size geçirerek acil sorunları çözebilirsiniz Kendi dosya nesnesini cmd.Cmd için yapıcıya.

senin amaçları için
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() 

, bu şeyleri yapmanın çok daha iyi bir yolu sağlar, çünkü sadece alınmayacak mı: İşte

(kısmen PyMOTW ödünç) bir örnek komut dosyası, yani sekme tamamlama gösteriyor Cmd örneğinin ürettiği çıktıyı yakalar.

Geçirdiğiniz dosya nesnesinin Cmd örneğinde de stdout özniteliği olarak bulunduğunu unutmayın.

+0

Teşekkür ederim, ama bu gerçekten yardımcı olmuyor. Cmd.Cmd .__ init__' dosyasında stdout'un None olup olmadığı kontrol edilir, eğer durum buysa, sys.stdout'un geri dönüşü vardır. Yani, tam olarak aynı, sys.stdin/out'a gitmek gibi. –

+0

@JonathanSlenders. İlk önce test etmeden çözümü teklif edemezdim. Benim için sorun sekmeyle tamamlanıyor. "Stdin" için hiçbir test yapmadım çünkü orijinal sorunuzun bir parçası değildi - ama [cmd.Cmd] için belgeleri okudum (http://docs.python.org/library/cmd.html # cmd.Cmd) ve [use_rawinput] (http://docs.python.org/library/cmd.html#cmd.Cmd.use_rawinput), bu konuyla ilgili önemli bilgilere sahip gibi görünüyor. – ekhumoro

+0

@JonathanSlenders. Cevabımı test için kullandığım komut dosyasıyla güncelledim. – ekhumoro