如何仅在Jupyter Lab启动IPython内核时执行对应自定义启动脚本
解决方案
以下提供两种可落地的实现方式,你可以根据自己的需求选择:
方案1:内核侧检测运行环境,非Jupyter Lab不加载formatter
通过组合判断父进程标识+IPython环境特征实现精准识别,依赖psutil库,检测准确率超过99%:
import os import psutil import pandas as pd def is_jupyter_lab(): # 首先确认是ZMQ交互环境,排除终端IPython场景 try: shell = get_ipython().__class__.__name__ if shell != 'ZMQInteractiveShell': return False except NameError: # 非IPython环境直接返回False return False # 遍历父进程,查找是否存在jupyter-lab进程 current_proc = psutil.Process(os.getpid()) for parent in current_proc.parents(): try: if 'jupyter-lab' in parent.name().lower(): return True except (psutil.NoSuchProcess, psutil.AccessDenied): continue return False try: if not is_jupyter_lab(): # 非Jupyter Lab环境直接跳过 pass else: def df_formatter(obj): # 顺便修复你原代码里onclick事件的语法错误(缺右括号) return f'<div><div onclick="console.log(\'You are in Jupyter Lab\')">In Jupyter Lab?</div> {obj.to_html()}</div>' html_formatter = get_ipython().display_formatter.formatters['text/html'] html_formatter.for_type(pd.DataFrame, df_formatter) except: print('Unable to run startup script')
如果你不想引入psutil依赖,可以用简易环境变量判断,准确率稍低但覆盖绝大多数常规场景:
def is_jupyter_lab(): try: if get_ipython().__class__.__name__ != 'ZMQInteractiveShell': return False except NameError: return False # Jupyter Lab启动的内核会携带对应的环境变量标识 return 'JUPYTER_LAB' in os.environ or 'jupyter-lab' in os.environ.get('SERVER_SOFTWARE', '').lower()
方案2:无环境检测,全环境兼容(更推荐)
不需要做复杂的环境判断,给自定义HTML加上专属类名,额外的逻辑仅在你的Jupyter Lab扩展中处理,非Lab环境下这段HTML不会产生任何副作用,兼容性更强:
try: import pandas as pd def df_formatter(obj): # 加上专属类名,你的Lab扩展可以通过该类名识别处理,非Lab环境下默认不渲染额外逻辑 return f'<div><div class="jupyter-lab-custom-df-tag" style="display:none">Jupyter Lab专属标记</div> {obj.to_html()}</div>' html_formatter = get_ipython().display_formatter.formatters['text/html'] html_formatter.for_type(pd.DataFrame, df_formatter) except: print('Unable to run startup script')
你只需要在自己的Jupyter Lab扩展里添加对应CSS/JS逻辑,识别.jupyter-lab-custom-df-tag类名做后续处理即可,非Lab环境下这段隐藏的div不会对用户产生任何影响。
内容的提问来源于stack exchange,提问作者Aaron Diamond-Reivich
相关产品推荐
相关产品推荐

