防止谷歌协作实验室中一个单元的多次运行

问题描述 投票:0回答:1

这里我定义了

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 链接 在此输入链接描述

python jupyter-notebook jupyter google-colaboratory
1个回答
0
投票

只需将

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)}")
© www.soinside.com 2019 - 2024. All rights reserved.