Если код, который вы запускаете, выводится на экран, и вы вызываете его с помощью root.tk.eval (), вы не можете его перехватить. Тем не менее, вы можете переопределить то, что "put" делает в коде tcl, и сделать так, как вам хочется. Это часть красоты Tcl - здесь нет зарезервированных слов.
Просто создайте в интерпретаторе tcl процедуру с именем «put», хотя убедитесь, что он имеет точно такой же интерфейс (т. Е. Уважает «-nonewline», может записывать в файлы и т. Д.). Когда команда put обычно печатает на экране, вы можете вместо этого заставить его делать что угодно, например записывать в сокет или просто возвращать строку, которую он должен напечатать.
Примерно (не проверено и игнорируется регистр с -nonewline):
root.tk.eval('''
rename puts original_puts
proc puts {args} {
if {[llength $args] == 1} {
return "=> [lindex $args 0]"
} else {
eval original_puts $args
}
}
''')
foo = root.tk.eval('puts "hello, world"')
print foo
=> hello, world
Потребуется немного усердия, чтобы удостовериться, что вы не нарушаете код tcl, который ожидает стандартное выражение «put», но это не так сложно сделать. Просто убедитесь, что у вас есть особые случаи для одного аргумента, первого аргумента «-nonewline» и там, где есть два аргумента (дескриптор файла и строка).
Это может усложниться, если вы вызываете eval, и он делает два оператора put, или делает put, а затем какой-то другой код, поскольку результат eval - это результат последнего оператора. Тем не менее, вы можете обойти это, поместив свой вывод буфера в глобальную переменную, а затем возвращать результат этой переменной каждый раз, когда вы делаете eval.
Итак, подумайте немного нестандартно, и вы сможете найти решение. Tcl очень гибкий.