Если я сделаю на Юпитере (и в питоне, и в шалфее) что-то вроде:
a = 42
b = 43
a + b
каким-то образом ему удастся понять, что этот процесс возвращает значение a + b, то есть 85 здесь:
Аналогично, если я просто сделаю:
a = 42
оно поймет, что возвращать нечего.
Теперь я хотел бы сделать что-то подобное для другого приложения (для кэширования результата операции Python)… как я могу получить эту информацию, в идеале, просто запустив код и добавив некоторый код Python для получения этой информации? Я пытался сделать:
a = 42
b = 43
a + b
print(_)
но это не получается. Я думал сделать что-нибудь глупое, например добавить res = перед последней строкой, но это могло потерпеть неудачу, например, если последняя строка имеет отступ и т. д. Как я могу элегантно получить эту информацию?
Я слежу за тем, что вы говорите, до начала абзаца I would like now to do something similar for a different application. Несколько вопросов, которые мне неясны: а) Будет ли это в Jupyter? Вы упоминаете только Python. б) Предполагается ли, что последний блок кода будет находиться в ячейке Jupyter? Отдельные строки в консоли Pyton? в) Вы пишете: «Как мне элегантно получить эту информацию?» Какую информацию из последнего раздела он должен получить? В заголовке написано: «Как получить последнюю переменную», то есть b. Должно ли в вашем заголовке быть «последнее выражение»?
«кэшировать результат операции Python» — вы ищете модуль Python Shelve? См. здесь.
Анализатор REPL знает, когда он проанализировал оператор выражения (оператор, состоящий из одного выражения), и REPL может использовать это для захвата значения и его печати, а также для неявного присвоения этого значения _. Это не связано с самой моделью данных Python, поэтому ваша попытка не удалась, если вы выполняли код из сценария в неинтерактивном режиме.
@Milan, по сути, я хочу эмулировать _ Python REPL (чтобы распечатать результат в файл) в простом скрипте Python. Как Юпитер это делает?
@Wayne: приложение предназначено для надежного экстернализации, библиотеки для кэширования кода, включая код Python, в LaTeX. Когда я набираю \cacheMe{some python code}, я хочу вычислить последнее выражение и сохранить результат в файле (возможно, выполняя различные операции над его типом, например, изображение и т. д.). Поэтому мне нужно знать, что писать в исходнике и как его скомпилировать (в идеале просто python myfile), чтобы он сохранял вывод в какие-то другие файлы.
@chepner, как мне адаптировать это к неинтерактивному варианту использования? Я предполагаю, что это каким-то образом возможно, поскольку Юпитер делает именно это, и более надежно, чем с _.
Jupiter реализует собственный REPL, как и CPython.
@chepner, значит, Юпитеру нужен синтаксический анализатор Python??






Используя ipython, существуют различные способы ссылки на предыдущую строку out:
In [113]: a = 42
...: b = 43
...: a + b
Out[113]: 85
In [114]: _ # also __ and ___
Out[114]: 85
In [115]: _113
Out[115]: 85
In [116]: Out[113]
Out[116]: 85
Out — список значений
Не существует способа сослаться на неназначенную строку в ячейке, как вы хотите:
a = 42
b = 43
a + b
print(?)
Использование a+b; также приведет к отключению последнего отображения/сохранения, так же, как и c = a+b.
_ также работает в простом интерактивном сеансе Python. jupyter/ipython расширяет эту коллекцию истории.
Спасибо, но я не могу использовать ipython, мне нужно сделать это на обычном Python. По сути, я хотел бы понять, как Jupyter может это сделать. Кроме того, _ не устойчив к таким вещам, как _ = 42, в то время как Jupyter удается сделать это правильно.
Я думал, вы спрашиваете об использовании jupyter/ipython, который имеет расширенный интерактивный REPL. Из ваших комментариев неясно, используете ли вы простой Python в режиме сценария, интерактивном режиме или пытаетесь разработать свой собственный REPL.
Я использую простой питон.
Все это является частью REPL, программы, которая принимает блоки текста (возможно, даже предоставляет возможность редактирования), выполняет их в сеансе Python (с глобальным пространством имен и т. д.) и получает обратно результат, который затем отображает (если не Никто). С помощью скрипта вам необходимо сохранить значения в переменных. Вы также можете использовать собственные pickle и shelf Python для сохранения переменных в файлах.
и как выполняется «выполнить и получить результат»? Используют ли они какой-то API-интерфейс Python для виртуальной машины и т. д.?
Я думаю, что об этом уже спрашивали в публикации под названием «Получить значение и тип переменной Python, аналогичной поведению Jupyter», где ОП уже добился значительного прогресса в поиске решения.
В результате подход заключается в использовании Python exec() для первого запуска кода в строках, а затем в использовании Python eval() для оценки последнего выражения, как это делает Jupyter с настройкой по умолчанию для InteractiveShell.ast_node_interactivity.
Я уточню* и перенесу свой ответ оттуда для конкретной ситуации с кодом здесь:
lines = """a = 42
b = 43
a + b"""
exec(lines,globals(),locals())
print(eval(lines.split("\n")[-1]))
Это печатает результат 85, как и ожидалось.
ФП выражает обеспокоенность по поводу отступов. Действительно, я отмечаю, что мое нынешнее предлагаемое решение потерпит неудачу, если последняя строка будет с отступом. Я считаю, что с этим можно справиться. Если последняя строка имеет какой-либо отступ, я могу собирать предыдущие строки до тех пор, пока уровень отступов не станет внешним уровнем. Затем используйте эти собранные строки как «последнее выражение» и оцените его. Однако я не сделал этого здесь, потому что решение без реализации этой части довольно ясно, и я пока не хотел делать его более запутанным из-за добавления этого.
Обязательно прочитайте предупреждение о exec() и eval() над , где я изначально разместил этот подход.
В ответ на комментарий я также подчеркну в ответе, что вы можете дополнительно сделать вещи более многофункциональными или комбинировать их другими способами, чтобы перенести возможности Jupyter/IPython в Python, поскольку вы можете выполнять импорт. На мой ответ в теме «Как мне создать функцию Python, где входные данные в коде Python и выходные данные представляют собой выходные данные, богатые ipython (в HTML)?» , у меня есть раздел «ОБНОВЛЕНИЕ В ОТВЕТ НА ПЕРВЫЙ КОММЕНТАРИЙ:», где я рассказываю об использовании IPython в качестве импорта в Python для захвата RichOutput, с этим подходом, который далее конкретизируется в демо-версии, которая включает в себя некоторые акробатические трюки, которые вы можете выполнить. использование методов и функций IPython в Jupyter.
*(В конечном итоге я уточнил свой старый ответ в другом месте, перенеся его сюда. Повторный просмотр ответа, который я там нашел, выявил проблему, заключавшуюся в том, что я не разделял правильно, чтобы получить фактическую последнюю строку для оценки. Мне просто повезло в прошлый раз последняя строка в моем исходном ответе была одним символом, и поэтому последняя строка и последний символ были одинаковыми в исходном случае, теперь я тоже это исправил.)
Спасибо! Обратите внимание, что ответ, на который вы ссылаетесь, содержит интересный код, который использует IPython в качестве библиотеки для выполнения кода.
«Обратите внимание, что ответ, на который вы ссылаетесь, содержит интересный код, который использует IPython в качестве библиотеки для выполнения кода». Я думаю, вы имеете в виду, что если кто-то перейдет по ссылке о предупреждении, он попадет в на мой ответ в теме «Как мне создать функцию Python, где входные данные в коде Python и выходные данные представляют собой выходные данные, богатые ipython (в HTML )?', у меня есть раздел «ОБНОВЛЕНИЕ В ОТВЕТ НА ПЕРВЫЙ КОММЕНТАРИЙ:», где я рассказываю об использовании IPython в качестве импорта в Python для захвата RichOutput, с помощью этого...
<продолжение> конкретизированная демо? Да, это так, но вы продолжали настаивать, что нельзя использовать IPython и использовать только чистый Python. Однако, возможно, вы не знали, что вы также можете импортировать IPython, и, возможно, вы сможете использовать его там, где работаете? Поскольку это может быть полезно другим, я тоже могу выделить это в своем ответе. Особенно в свете того, что IPython поддерживает больше того, что вы изначально описали, «из коробки», и поэтому здесь могут оказаться другие, кто сможет использовать IPython в качестве импорта в Python.
Да, я предпочитаю чистый Python, поскольку у моих пользователей может не быть установлен ipython, но я также не знал о том, что ipython можно импортировать как библиотеку. Знаете ли вы, можно ли это применить и к шалфею?
Я не знаю, что конкретно вы подразумеваете под Сейджем? Раньше я использовал SageMath Online; однако это было некоторое время назад, и на данный момент я не уверен в его способностях по сравнению со стандартным Jupyter.
Хорошо спасибо. У Sage есть исполняемый файл sage foo.sage, который запускает код в foo.sage, и я не уверен, сможем ли мы проделать такой же трюк.
Я вижу кое-что из этого здесь . Кажется, главная страница ссылки находится здесь . Он очень похож на здесь, он может импортировать множество вещей из Python.
Я вижу кое-что из этого здесь . Кажется, главная страница ссылки находится здесь . Похоже, что на основе здесь он может импортировать много вещей из Python.
какую «информацию» вы хотите получить? результаты a+b... присвоения?! в = а+б