Вывод в стиле интерпретатора в Python 3 (может быть, о sys.displayhook?)
Я делаю небольшое игрушечное командное окно с Tk, и в настоящее время пытаюсь заставить его скопировать некоторое поведение интерпретатора.
Я никогда раньше не изучал интерпретатор, но его решение о том, когда печатать значение, немного загадочно.
>>> 3 + 4 # implied print(...)
7
>>> 3 # implied print(...)
3
>>> a = 3 # no output, no implied print(...), bc result is None maybe?
>>> None # no output, no print(...) implied... doesn't like None?
>>> print(None) # but it doesn't just ban all Nones, allows explicit print()
None
>>> str(None) # unsurprising, the string 'None' is just a string, and echoed
'None'
Цель состоит в том, чтобы подражать этому поведению, печатая одни Nones, а не другие (сделаны немного более сложными, потому что я не совсем уверен, каковы правила).
Итак, обращаясь к моей программе, у меня есть history_text и entry_text, которые являются StringVar(), которые контролируют метку над полем ввода в окне Tk. Затем следующее событие связывается с клавишей Return, чтобы обработать команды и обновить историю с результатом.
def to_history(event):
print("command entered") # note to debugging window
last_history = history_text.get()
# hijack stdout
buffer = io.StringIO('')
sys.stdout = buffer
# run command, output to buffer
exec(entry_text.get())
# buffered output to a simple string
buffer.seek(0)
buffer_str = ''
for line in buffer.readlines():
# maybe some rule goes here to decide if an implied 'print(...)' is needed
buffer_str = buffer_str + line + '\n'
# append typed command for echo
new_history = entry_text.get() + '\n' + buffer_str
# cleanup (let stdout go home)
sys.stdout = sys.__stdout__
buffer.close()
history_text.set(last_history + "\n" + new_history)
entry_text.set('')
Таким образом, он не предоставляет никакого вывода для простой записи "3" или "None" или даже "3 + 4". Кажется, что добавление неявного оператора print() все время печатает слишком часто, я не пропускаю печать для операторов типа "None" или "a = 3".
Я нашел некоторую документацию для sys.displayhook, которая, кажется, определяет, когда интерпретатор действительно отобразит результат, но я не уверен, как его использовать здесь. Я подумал, что могу просто обернуть sys.displayhook() вокруг моего вызова exec() и заставить его выполнять всю эту работу за меня... но обнаружил, что это не подразумевает операторов print() для операторов типа '3 + 4' или '3'.
Какие-либо предложения? Я на правильном пути с sys.displayhook?
1 ответ
Переводчик распечатывает repr(result)
только если result is not None
,
Там нет "подразумевается print
s", как вы думали.
3 + 4
результаты к7
, такrepr(7)
печатаетсяa = 3
это задание, я думаю, что ничего не печатается, потому что он не работает сeval
None
результаты кNone
так что ничего не печатаетсяprint(None)
результаты кNone
(посколькуprint
функция ничего не возвращает), поэтому ничего не печатается. Тем не менееprint
сама функция напечаталаNone
,
Я, честно говоря, не читал ваш код, но вот функция, которая принимает строку с кодом и выдает тот же результат, что и интерпретатор:
def interactive(code):
try:
result = eval(code)
if result is not None:
print(repr(result))
except SyntaxError:
exec(code)