現在、コマンドラインインターフェイス用のcmd.Cmdモジュールを使用するアプリケーションがあり、タブ補完は完全に機能します。sys.stdoutが置き換えられたときのcmd.CmdのPython readlineタブ補完
今、私は別のオブジェクトと、sys.stdout
を交換したいのですが(書かれているもの捕捉するために、例えば。)
スニペットは、理論的には完全に透明でなければならないの後、すべての設定/操作するには、GetとしてStdオブジェクトはsys.__stdout__
にリダイレクトされます。例えば
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()
はまだしかし、Cmd.cmd
のreadlineタブ補完は、もはや今動作しない1. を印刷されません...
さて、ファイルを継承してみましょう。
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がファイルオブジェクトである)そして今、私が手:
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
をどういうわけか、私は推測する、Pythonがあります過度に最適化し、Std.writeをバイパスします。
readlineサポートを失うことなく、stdoutを置き換えるにはどうすればよいですか?
ジョナサン
-edit-
私はまた、sys.stdinをを交換しようとしています。 raw_inputがreadlineサポートに使用され、Pythonのraw_inputがファイル記述子を受け入れないため、cmd.Cmdに渡すことはできません。 sys.stdinに割り当てられているptyに戻ります。
新しいpty(os.openpty()を使用して)を作成し、このペアをsys.stdin/outに割り当てると、そのptyを通じてreadline autocompletionが完璧に機能しますが、プロキシオブジェクトにラップされると、オートコンプリートはありません。
のreadlineのソースを理解しようとするが、それは簡単ではありません。 http://svn.python.org/projects/python/branches/release25-maint/Modules/readline.c
ありがとうございますが、これは本当に役に立ちません。 'cmd.Cmd .__ init__'では、stdoutがNoneであるかどうかチェックされます。そうであれば、sys.stdoutにフォールバックします。つまり、sys.stdin/outignと同じです。 –
@ JonathanSlenders私はそれを最初にテストせずにソリューションを提供していないでしょう。私にとっては、タブ補完で問題を解決します。 '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
@JonathanSlenders私はテストのために使ったスクリプトで自分の答えを更新しました。 – ekhumoro