В настоящее время у меня есть приложение, которое использует модуль cmd.Cmd для интерфейса командной строки, завершение табуляции работает отлично.
Теперь я хотел бы заменить sys.stdout
другим объектом (например, для захвата того, что пишется).
Следующий фрагмент должен быть полностью прозрачным в теории, так как каждая операция get / set для объекта Std перенаправляется на actial 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()
все равно будет печатать 1.
Однако завершение чтения строки табуляции Cmd.cmd
больше не работает ...
Хорошо, давайте наследуем из файла. (стандартный вывод является файловым объектом.)
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
Каким-то образом, я думаю, Python что-то переоптимизирует и обходит Std.write.
Что я должен сделать, чтобы заменить стандартный вывод, не теряя поддержки readline ...?
Jonathan
-edit-
Я также пытаюсь заменить sys.stdin.
Передача его в cmd.Cmd не работает, потому что raw_input используется для поддержки readline, а Python raw_input не принимает файловый дескриптор. Он возвращается к любому pty, назначенному для sys.stdin.
Когда я создаю новый pty (через os.openpty ()) и назначаю эту пару для sys.stdin / out, автодополнение readline через этот pty работает отлично, но опять же, когда он помещается в прокси-объект, он работает, но без автозаполнения.
Попытка понять источник readline, но это нелегко:
http://svn.python.org/projects/python/branches/release25-maint/Modules/readline.c