66

我想知道是否可以sys.argv在 jupyter/ipython 笔记本中使用命令行参数填充(或其他结构),类似于通过 python 脚本完成的方式。

例如,如果我要运行如下 python 脚本:

python test.py False

然后sys.argv将包含论点False。但是,如果我以类似的方式运行 jupyter notebook:

jupyter notebook test.ipynb False

然后命令行参数丢失。有没有办法从笔记本本身访问这个参数?

4

11 回答 11

35

经过大量环顾后,我发现自定义库非常繁琐,但用几行代码解决了它,我认为这很漂亮。我使用 nbconvert 最终得到一个 html 报告作为输出,其中包含笔记本中的所有图形和降价,但像往常一样通过最小的 python 包装器接受命令行参数:

python 文件 test_args.py (正常使用命令行参数):

import sys,os
IPYNB_FILENAME = 'test_argv.ipynb'
CONFIG_FILENAME = '.config_ipynb'

def main(argv):
    with open(CONFIG_FILENAME,'w') as f:
        f.write(' '.join(argv))
    os.system('jupyter nbconvert --execute {:s} --to html'.format(IPYNB_FILENAME))
    return None

if __name__ == '__main__':
    main(sys.argv)

笔记本包含:

import sys,os,argparse
from IPython.display import HTML
CONFIG_FILE = '.config_ipynb'
if os.path.isfile(CONFIG_FILE):
    with open(CONFIG_FILE) as f:
        sys.argv = f.read().split()
else:
    sys.argv = ['test_args.py', 'input_file', '--int_param', '12']

parser = argparse.ArgumentParser()
parser.add_argument("input_file",help="Input image, directory, or npy.")
parser.add_argument("--int_param", type=int, default=4, help="an optional integer parameter.")
args = parser.parse_args()
p = args.int_param
print(args.input_file,p)

我可以像往常一样运行带有解析参数的python笔记本:

python test_args.py my_input_file --int_param 12

我倾向于将带有 argparse 调用的块粘贴到 python 包装器中,以便 python 脚本捕获命令行错误并且 -h 可以正常工作。

于 2018-01-24T03:06:23.190 回答
20

我发现有两个项目可以满足您的要求

  • Papermill将在您的笔记本中添加一个单元格,其中包含您在命令行上传递给它的参数。所以这很简单,你在第一个单元格中定义你的默认值(应该有parameters标签)
  • nbparameterise它是一个类似的概念,但你不要用默认值标记你的单元格,它必须是第一个。

这是讨论这个问题的好资源:https ://github.com/jupyter/help/issues/218

于 2018-11-14T21:37:49.623 回答
11

我认为这个要点可以帮助你:https ://gist.github.com/gbishop/acf40b86a9bca2d571fa

这是一个简单的参数解析器的尝试,主要用于键=值对,可以在命令行和 IPython 笔记本中使用。它支持笔记本 URL 中的查询参数和笔记本的运行命令。

于 2016-07-06T09:04:18.910 回答
9

使用args = parser.parse_args(args=[])会起作用。

或者为了测试,您可以将其声明为类格式。

class Args:
  data = './data/penn'
  model = 'LSTM'
  emsize = 200
  nhid = 200

args=Args()
于 2018-10-02T15:09:24.237 回答
9

如果目标是运行带有从命令行传递的可配置参数的笔记本,我认为最简单的方法是使用环境变量,如下所示:

NB_ARGS=some_args jupyter nbconvert --execute --to html --template full some_notebook.ipynb

然后在笔记本中,您可以import os使用os.environ['NB_ARGS']. 例如,变量值可以是一些包含键值对或 json 的文本。

于 2020-09-01T20:27:18.273 回答
9

在 Jupyter 单元格的顶部,放置如下一行:

%%python - --option1 value1 --option2 value2 --etc

在您的示例中:

%%python - True

这将使用提供的参数在命令行中运行您的脚本。

例子:

%%python - --option1 value1 --option2 value2 --etc

import sys

if __name__ == '__main__':
    print(sys.argv)

将输出:

['-', '--option1', 'value1', '--option2', 'value2', '--etc']

希望能帮助到你。

于 2021-01-01T14:45:59.413 回答
2

sys.argv产生 a list,所以我用

sys.argv.append('hello')

在一个 jupyter 笔记本中,它允许我附加额外的成员并假装我正在从命令行传递参数。

于 2019-03-23T02:39:33.397 回答
1

一种解决方法是让 jupyter notebook 从文件中读取参数。从命令行,修改文件并运行笔记本。

于 2020-04-02T05:09:45.463 回答
1

我假设您只想解析一些笔记本的参数,但没有必要使用命令行。

如果你想解析类似的命令。

python script.py --a A --b B

您可以在笔记本中使用以下代码:

cmd = '--a A --b B'
args = args = parser.parse_args(cmd)

对于,您可以在此处parse_args找到更多信息。

于 2020-11-13T11:42:42.970 回答
0

一个简单而幼稚的解决方案是将以下代码段放在程序的第一行:

import sys
sys.argv = "your expected command line arguments here".split()

执行此命令后,类似的包argparse将正常运行。

因此,您可以在 jupyter 实验室服务器中运行您的脚本,而无需打开终端并输入您的参数。

于 2021-04-05T03:13:45.373 回答
0

我尝试了上面列出的答案,并提出了不同的解决方案。

我的原始代码是

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to input image")
ap.add_argument("-y", "--yolo", required=True, help="base path to YOLO directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5, help="minimum probability to filter weak detections")
ap.add_argument("-t", "--threshold", type=float, default=0.3, help="threshold when applying non-maxima suppression")
args = vars(ap.parse_args())

我试图做一个类

Class Args():
    image='photo.jpg'
    yolo='yolo-coco'
    confidence=0.5
    threshold=0.3

args=Args()

但更多的代码片段产生了错误。

所以我打印args了之后vars(ap.parse_args())发现它是一本字典。

所以只需为原始参数创建一个字典:

args={"image":  'photo.jpg', "yolo":  'yolo-coco', "confidence": 0.5,"threshold": 0.3}
于 2021-04-08T18:13:29.007 回答