У меня есть пример кода Python, которым я хотел бы поделиться, который должен делать что-то другое при выполнении в терминале Python / IPython или в записной книжке IPython.
Как я могу проверить свой код Python, работает ли он в записной книжке IPython?
python
ipython
ipython-notebook
Кристоф
источник
источник
Ответы:
Вопрос в том, что вы хотите выполнить по-другому.
В IPython мы делаем все возможное, чтобы ядро не знало, к какому типу интерфейса подключен, и на самом деле вы даже можете подключить ядро ко многим различным интерфейсам одновременно. Даже если вы можете взглянуть на тип
stderr/out
чтобы узнать, используете ли вы ядро ZMQ или нет, это не гарантирует вам того, что у вас есть на другой стороне. У вас может вообще не быть фронтендов.Вам, вероятно, следует писать свой код независимо от внешнего интерфейса, но если вы хотите отображать разные вещи, вы можете использовать систему расширенного отображения (ссылка закреплена на версии 4.x IPython) для отображения разных вещей в зависимости от внешнего интерфейса, но будет выбирать интерфейс, а не библиотека.
источник
\x1b[A
(перемещение вверх), поэтому невозможно распечатать вложенные полосы . Нет проблем с ipywidgets , мы можем использовать собственные виджеты Jupyter для отображения индикаторов выполнения. Но тогда у нас есть два разных средства отображения индикатора выполнения, и приложение может захотеть узнать, что такое среда отображения, чтобы адаптировать и распечатать совместимый индикатор.%matplotlib inline
когда она работает как ноутбук, но не в терминале, поскольку это не требуется.Следующее сработало для моих нужд:
Он возвращается
'TerminalInteractiveShell'
на терминал IPython,'ZMQInteractiveShell'
на Jupyter (ноутбук И qtconsole) и терпит неудачу (NameError
) на обычном интерпретаторе Python. Методget_python()
Кажется, что доступен в глобальном пространстве имен по умолчанию при запуске IPython.Обернув его простой функцией:
def isnotebook(): try: shell = get_ipython().__class__.__name__ if shell == 'ZMQInteractiveShell': return True # Jupyter notebook or qtconsole elif shell == 'TerminalInteractiveShell': return False # Terminal running IPython else: return False # Other type (?) except NameError: return False # Probably standard Python interpreter
Вышеупомянутое было протестировано с Python 3.5.2, IPython 5.1.0 и Jupyter 4.2.1 на macOS 10.12 и Ubuntu 14.04.4 LTS.
источник
jupyter console
, к сожалению,get_ipython()
возвращает экземплярZMQInteractiveShell
такжеget_ipython().__class__.__module__ == "google.colab._shell"
test.py
затем запустилfrom test import isnotebook; print(isnotebook())
в блокноте Jupyter, она распечатаетсяTrue
. (Проверено на сервере Notebook версий 5.2.1 и 6.0.1.)Чтобы проверить, находитесь ли вы в записной книжке, что может быть важно, например, при определении того, какой тип индикатора выполнения использовать, это сработало для меня:
def in_ipynb(): try: cfg = get_ipython().config if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook': return True else: return False except NameError: return False
источник
cfg['IPKernelApp']['parent_appname']
есть aIPython.config.loader.LazyConfigValue
, который не сравниваетсяTrue
с"iypthon-notebook"
IPython.kernel.zmq.zmqshell.ZMQInteractiveShell
экземпляр в ipynb (Jupyter) иIPython.terminal.interactiveshell.TerminalInteractiveShell
REPL терминала, если вам нужно различать ноутбуки и терминал / консоли (что влияет на построение графика).try
блока на:return str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>"
shell='PyDevTerminalInteractiveShell'
при проверке имени класса.Вы можете проверить, находится ли Python в интерактивном режиме, с помощью следующего фрагмента [1] :
def is_interactive(): import __main__ as main return not hasattr(main, '__file__')
Я нашел этот метод очень полезным, потому что я много делаю прототипы в блокноте. В целях тестирования я использую параметры по умолчанию. В противном случае я читаю параметры из
sys.argv
.from sys import argv if is_interactive(): params = [<list of default parameters>] else: params = argv[1:]
После реализации
autonotebook
вы можете определить, находитесь ли вы в записной книжке, используя следующий код.def in_notebook(): try: from IPython import get_ipython if 'IPKernelApp' not in get_ipython().config: # pragma: no cover return False except ImportError: return False return True
источник
is_interactive()
не делает различий между ноутбуком и консолью.%run
из ipython не является интерактивной. Вы можете возразить, что так и должно быть, но это все равно ошибка.is_interactive
) мне кажется в основном неуместной для вопроса. Это тоже сомнительной правильности; как указывает @marscher, он считает все, что запущено,python -c
как находящееся в «интерактивном» режиме, даже если это не так. Я не хочу делать это сам, так как это не мой ответ, но я думаю, что это можно было бы улучшить, просто удалив всю первую половину ответа.Недавно я столкнулся с ошибкой в записной книжке Jupyter, которая требует обходного пути, и я хотел сделать это без потери функциональности в других оболочках. Я понял, что решение keflavich в данном случае не работает, потому что
get_ipython()
оно доступно только напрямую с ноутбука, а не из импортных модулей. Итак, я нашел способ определить из моего модуля, импортирован и используется ли он из записной книжки Jupyter или нет:import sys def in_notebook(): """ Returns ``True`` if the module is running in IPython kernel, ``False`` if in IPython shell or other Python shell. """ return 'ipykernel' in sys.modules # later I found out this: def ipython_info(): ip = False if 'ipykernel' in sys.modules: ip = 'notebook' elif 'IPython' in sys.modules: ip = 'terminal' return ip
Комментарии приветствуются, если это достаточно надежно.
Аналогичным образом можно получить некоторую информацию о клиенте, а также о версии IPython:
import sys if 'ipykernel' in sys.modules: ip = sys.modules['ipykernel'] ip_version = ip.version_info ip_client = ip.write_connection_file.__module__.split('.')[0] # and this might be useful too: ip_version = IPython.utils.sysinfo.get_sys_info()['ipython_version']
источник
'Ipython' in sys.modules
оценивается какFalse
. Возможно вы имеете в виду'IPython' in sys.modules
? ЭтоTrue
в моей среде Jupyter. Вsys.modules
словаре тоже нет'ipykernel'
ключа - при работе внутри записной книжки.Протестировано на Python 3.7.3
Реализации CPython имеют имя,
__builtins__
доступное как часть их глобальных переменных, которые, кстати,. можно получить с помощью функции globals ().Если скрипт выполняется в среде Ipython, он
__IPYTHON__
должен быть атрибутом__builtins__
.Поэтому приведенный ниже код возвращается,
True
если выполняется под Ipython, иначе он даетFalse
hasattr(__builtins__,'__IPYTHON__')
источник
Следующее описывает случаи https://stackoverflow.com/a/50234148/1491619 без необходимости анализировать вывод
ps
def pythonshell(): """Determine python shell pythonshell() returns 'shell' (started python on command line using "python") 'ipython' (started ipython on command line using "ipython") 'ipython-notebook' (e.g., running in Spyder or started with "ipython qtconsole") 'jupyter-notebook' (running in a Jupyter notebook) See also https://stackoverflow.com/a/37661854 """ import os env = os.environ shell = 'shell' program = os.path.basename(env['_']) if 'jupyter-notebook' in program: shell = 'jupyter-notebook' elif 'JPY_PARENT_PID' in env or 'ipython' in program: shell = 'ipython' if 'JPY_PARENT_PID' in env: shell = 'ipython-notebook' return shell
источник
jupyter
, является ли этоjupyter console
,jupyter qtconsole
илиjupyter notebook
.Я бы рекомендовал избегать обнаружения определенных интерфейсов, потому что их слишком много . Вместо этого вы можете просто проверить, работаете ли вы из среды iPython:
def is_running_from_ipython(): from IPython import get_ipython return get_ipython() is not None
Вышеупомянутое будет возвращено,
False
если вы вызываетеrunning_from_ipython
из обычной командной строки python. Когда вы вызываете его из Jupyter Notebook, JupyterHub, оболочки iPython, Google Colab и т. Д., Он вернетсяTrue
.источник
get_ipython()
возвращается<ipykernel.zmqshell.ZMQInteractiveShell at 0x7f750ba94320>
.get_ipython() is not None
возвращаюсьTrue
.Все, что вам нужно сделать, это поместить эти две ячейки в начало вашей записной книжки:
Ячейка 1: (помечена как «код»):
is_notebook = True
Ячейка 2: (помечена как "Raw NBConvert"):
is_notebook = False
Первая ячейка будет выполняться всегда, а вторая ячейка будет выполняться только при экспорте записной книжки в виде сценария Python.
Позже вы сможете проверить:
if is_notebook: notebook_code() else: script_code()
Надеюсь это поможет.
источник
Как насчет чего-то вроде этого:
import sys inJupyter = sys.argv[-1].endswith('json') print(inJupyter);
источник
Насколько я знаю, здесь есть 3 вида ipython, которые использовали
ipykernel
ipython qtconsole
(для краткости "qtipython")использовать
'spyder' in sys.modules
может отличить spyderно для qtipython и jn трудно отличить причину
у них одинаковая
sys.modules
и та же конфигурация IPython:get_ipython().config
Я считаю, что qtipython и jn отличаются:
при первом запуске
os.getpid()
в оболочке IPython получите номер pidзатем беги
ps -ef|grep [pid number]
мой qtipython pid - 8699
yanglei 8699 8693 4 20:31 ? 00:00:01 /home/yanglei/miniconda2/envs/py3/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-8693.json
мой jn pid - 8832
yanglei 8832 9788 13 20:32 ? 00:00:01 /home/yanglei/miniconda2/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-ccb962ec-3cd3-4008-a4b7-805a79576b1b.json
разница между qtipython и jn - это имя json ipython, имя jn jn длиннее, чем имя qtipython
Итак, мы можем автоматически определять всю среду Python, используя следующий код:
import sys,os def jupyterNotebookOrQtConsole(): env = 'Unknow' cmd = 'ps -ef' try: with os.popen(cmd) as stream: if not py2: stream = stream._stream s = stream.read() pid = os.getpid() ls = list(filter(lambda l:'jupyter' in l and str(pid) in l.split(' '), s.split('\n'))) if len(ls) == 1: l = ls[0] import re pa = re.compile(r'kernel-([-a-z0-9]*)\.json') rs = pa.findall(l) if len(rs): r = rs[0] if len(r)<12: env = 'qtipython' else : env = 'jn' return env except: return env pyv = sys.version_info.major py3 = (pyv == 3) py2 = (pyv == 2) class pyi(): ''' python info plt : Bool mean plt avaliable env : belong [cmd, cmdipython, qtipython, spyder, jn] ''' pid = os.getpid() gui = 'ipykernel' in sys.modules cmdipython = 'IPython' in sys.modules and not gui ipython = cmdipython or gui spyder = 'spyder' in sys.modules if gui: env = 'spyder' if spyder else jupyterNotebookOrQtConsole() else: env = 'cmdipython' if ipython else 'cmd' cmd = not ipython qtipython = env == 'qtipython' jn = env == 'jn' plt = gui or 'DISPLAY' in os.environ print('Python Envronment is %s'%pyi.env)
исходный код находится здесь: Обнаружение среды Python, особенно отличить Spyder, Jupyter notebook, Qtconsole.py
источник
Я использую Django Shell Plus для запуска IPython, и я хотел сделать «запуск в записной книжке» доступным в качестве значения настроек Django.
get_ipython()
недоступен при загрузке настроек, поэтому я использую это (что не является пуленепробиваемым, но достаточно хорошо для локальных сред разработки, в которых он используется):import sys if '--notebook' in sys.argv: ENVIRONMENT = "notebook" else: ENVIRONMENT = "dev"
источник
Предполагая, что у вас есть контроль над Jupyter Notebook, вы можете:
установить значение среды в ячейке, которая использует это как флаг в вашем коде . Поместите уникальный комментарий в эту ячейку (или во все ячейки, которые вы хотите исключить)
# exclude_from_export
% set_env is_jupyter = 1
Экспортируйте записную книжку как скрипт Python для использования в другом контексте. При экспорте будут исключены закомментированные ячейки, а затем и код, задающий значение среды. Примечание: замените your_notebook.ipynb именем вашего фактического файла записной книжки.
jupyter nbconvert --to сценарий --RegexRemovePreprocessor.patterns = "['^ # exclude_from_export']" your_notebook.ipynb
Это сгенерирует файл, в котором не будет установлен флаг среды jupyter, позволяющий детерминированному выполнению кода, который его использует.
источник