这里我定义了
run_once
单元魔法,以防止谷歌合作实验室中同一代码中的多个输出。如果在代码未更改的情况下发生这种情况,它将显示历史输出,而不像第一次运行那样进行实际计算。
#@title Mendefinisikan Fungsi `run_once`
from IPython.core.magic import register_cell_magic
from IPython.display import display, HTML
from google.colab import output
from hashlib import sha1
import time
import os
@register_cell_magic
def run_once(line: str, cell: str):
"""
This is a custom cell magic command in order to prevent multiple runs, so the cell must be run once for every runtime.
If the cell has already run before, then it will display the history output.
Usage: %%run_once
"""
try:
# Argument of this magic cell is specifying tracker directory
tracker_dir = line
if len(tracker_dir) == 0:
tracker_dir = './.run_once' # Set default if not specified.
# Create input-output tracker directory
if not os.path.exists(tracker_dir):
os.makedirs(tracker_dir)
# Get cell id by cell changes with SHA-1 as identifier
cell_id = sha1(cell.encode('utf-8')).hexdigest()
# Check wether cell_id.html already exists. (Imply the cell already run)
if os.path.exists(f'{tracker_dir}/{cell_id}.html'):
with open(f'{tracker_dir}/{cell_id}.html', 'r') as file_cell_output:
html_output = file_cell_output.read()
last_created = time.strftime('%Y-%m-%d %H:%M:%S UTC+00', time.gmtime(os.path.getctime(f'{tracker_dir}/{cell_id}.html')))
print(f'This cell ({cell_id}) already ran before, last run was:', last_created, ', displaying history output...\n')
display(HTML(html_output))
return
# Execute actual code.
exec(cell, globals(), locals())
# After code has executed, it will contains some output. Save it!
html_output = output.eval_js('document.getElementById("output-area").innerHTML;')
with open(f'{tracker_dir}/{cell_id}.html', 'w') as file_cell_output:
file_cell_output.write(html_output)
# Also save the cell code for archive purpose
with open(f'{tracker_dir}/{cell_id}.cell.py', 'w') as file_cell_input:
file_cell_input.write(cell)
except Exception as e:
print(f"run_once error: {str(e)}")
使用示例:
%%run_once
print("This is an example of cell that can't be runs multiple times")
但是我有问题,它不是 python 语法,例如 shell 命令
%%run_once
!ls current_directory
返回:
run_once error: invalid syntax (<string>, line 2)
而且定义全局变量似乎不起作用:
#CELL A
%%run_once
myvar = 5
当我在单元格 B 中
print(myvar)
时,它会说myvar
未定义。但反之亦然,我在单元格中定义没有魔法单元myvar
的run_once
,然后在处于模式myvar
的单元格中打印
run_once
我怀疑是因为它正在使用
exec
。
有关其用法的更多屏幕主机,我提供了 github 链接 在此输入链接描述
只需将
exec(cell)
替换为 get_ipython.run_cell(cell)
因此整体魔法单元定义将如下所示:
#@title Mendefinisikan Fungsi `run_once`
from IPython.core.magic import register_cell_magic
from IPython.display import display, HTML
from google.colab import output
from hashlib import sha1
import time
import os
@register_cell_magic
def run_once(line: str, cell: str):
"""
This is a custom cell magic command in order to prevent multiple runs, so the cell must be run once for every runtime.
If the cell has already run before, then it will display the history output.
Usage: %%run_once
"""
try:
# Argument of this magic cell is specifying tracker directory
tracker_dir = line
if len(tracker_dir) == 0:
tracker_dir = './.run_once' # Set default if not specified.
# Create input-output tracker directory
if not os.path.exists(tracker_dir):
os.makedirs(tracker_dir)
# Get cell id by cell changes with SHA-1 as identifier
cell_id = sha1(cell.encode('utf-8')).hexdigest()
# Check wether cell_id.html already exists. (Imply the cell already run)
if os.path.exists(f'{tracker_dir}/{cell_id}.html'):
with open(f'{tracker_dir}/{cell_id}.html', 'r') as file_cell_output:
html_output = file_cell_output.read()
last_created = time.strftime('%Y-%m-%d %H:%M:%S UTC+00', time.gmtime(os.path.getctime(f'{tracker_dir}/{cell_id}.html')))
print(f'This cell ({cell_id}) already ran before, last run was:', last_created, ', displaying history output:\n')
display(HTML(html_output))
return
# Actual computation
get_ipython().run_cell(cell)
# After code has executed, it will contains some output. Save it!
html_output = output.eval_js('document.getElementById("output-area").innerHTML;')
with open(f'{tracker_dir}/{cell_id}.html', 'w') as file_cell_output:
file_cell_output.write(html_output)
# Also save the cell code for archive purpose
with open(f'{tracker_dir}/{cell_id}.cell.py', 'w') as file_cell_input:
file_cell_input.write(cell)
except Exception as e:
print(f"run_once error: {str(e)}")