【发布时间】:2013-11-03 23:08:12
【问题描述】:
有没有办法从%%bash 或其他%%script 单元格中访问当前python 内核中的变量?
也许作为命令行参数或环境变量?
【问题讨论】:
标签: ipython-notebook ipython-magic
有没有办法从%%bash 或其他%%script 单元格中访问当前python 内核中的变量?
也许作为命令行参数或环境变量?
【问题讨论】:
标签: ipython-notebook ipython-magic
Python 变量可以在%%bash 或%%script 单元格的第一行访问,因此可以作为命令行参数传递给脚本。例如,使用 bash 你可以这样做:
%%bash -s "$myPythonVar" "$myOtherVar"
echo "This bash script knows about $1 and $2"
-s 命令行选项允许您将位置参数传递给 bash,通过 $n 访问第 n 个位置参数。请注意,实际分配给 bash 位置变量的是str(myPythonVariable) 的结果。如果您传递包含引号字符(或其他 bash 敏感字符)的字符串,则需要使用反斜杠对其进行转义(例如:\")。
引号很重要 - 没有它们,python 变量(字符串表示形式)会按空格分隔,因此如果 myPythonVar 是 datetime.datetime 而 str(myPythonVar) 是 "2013-10-30 05:04:09.797507",则上述 bash 脚本将接收 3 个位置变量,前两个值为2013-10-30 和05:04:09.797507。它的输出是:
This bash script knows about 2013-10-30 and 05:04:09.797507
如果你想命名变量并且你正在运行 linux,这里有一个方法:
%%script env my_bash_variable="$myPythonVariable" bash
echo myPythonVariable\'s value is $my_bash_variable
您可以指定多个变量赋值。再次提防引号和其他类似的事情(这里 bash 会痛苦地抱怨!)。要了解其工作原理,请参阅 env 手册页。
【讨论】:
要在使用语法!<some command> 运行的bash 命令中包含python 变量,您可以使用{<variable>},如下所示:
In [1]: for i in range(3):
...: !echo {i+1}
...:
1
2
3
虽然这与 OP 的要求略有不同,但它在执行脚本任务时密切相关且有用。 This post 有更多关于在 IPython 和 Jupyter 笔记本中使用 shell 命令的精彩技巧和示例。
【讨论】:
!。你甚至可以n = !echo {i + 1}。
一个问题是,如果您要提供给 bash 的变量是一个列表,那么它不会按预期工作。
例如,在一个 python 单元格中:
l = ['A', 'B', 'C']
那么如果你直接把它交给下一个单元格的魔法选项:
%%bash -s "$l"
for i in $1
do
echo $i
done
它会像这样奇怪地分裂:
['A',
'B',
'C']
最简单的答案是将代码放在大括号{} 中以将您的python 列表转换为bash 列表,如下所示:
%%bash -s "{" ".join(l)}"
for i in $1
do
echo $i
done
这给出了预期的输出:
A
B
C
【讨论】:
%%bash 魔法正在寻找} 并且并不关心它。
如果像我这样的人最终在这里寻找如何在使用! 运行命令时使用 Python 变量,只需为变量添加前缀$ 就可以了:
!echo $foobar
【讨论】:
如果您需要向 bash 脚本传递除简单变量之外的其他内容,请注意一个变化:
%%bash -s $dict['key1'] $dict['key2'] $dict['key3']
出现了可怕的错误,但是
%%bash -s {dict['key1']} {dict['key2']} {dict['key3']}
效果很好。
【讨论】:
如果你愿意定义一个新的魔法,你可以使用 Python 字符串模板:
from IPython import get_ipython
from IPython.core.magic import register_cell_magic
ipython = get_ipython()
@register_cell_magic
def pybash(line, cell):
ipython.run_cell_magic('bash', '', cell.format(**globals()))
然后如果你在 Python 中定义一个变量,比如:
test = 'Python variables'
你可以使用它:
%%pybash
echo '{test} will be expanded'
echo '{{double braces will be replaced with single braces}}'
导致:
Python variables will be expanded
{double braces will be replaced with single braces}
【讨论】:
不,%%script 魔法是自动生成的,不会进行任何魔法进程间数据通信。 (%%R 的情况并非如此,但它在其自己的班级中是一个单独的魔法,R peoples 会格外小心)
但是编写自己的魔法并不难。
【讨论】:
%%bash -c 'myvar=$MyPythonVar bash',然后可能是单元格下一行的echo $myvar?这行得通...
%%bash .. 单元格没有其他内容,它会抱怨,如果我把ls 放在那里,操作系统会返回/bin/echo: /bin/echo: cannot execute binary file(至少在我的mac 上-但我认为ubuntu 做了类似的事情)
{..} 语法,除了第一行。所以你需要自己写。
#%%exppose myPythonVar 这样的特殊 cmets 然后当你看到 $myPythonVar 或其他东西时将它的值替换到脚本中......也许有一天我会试一试(: