【问题标题】:Can I access python variables within a `%%bash` or `%%script` ipython notebook cell?我可以在 `%%bash` 或 `%%script` ipython notebook 单元格中访问 python 变量吗?
【发布时间】:2013-11-03 23:08:12
【问题描述】:

有没有办法从%%bash 或其他%%script 单元格中访问当前python 内核中的变量?

也许作为命令行参数或环境变量?

【问题讨论】:

    标签: ipython-notebook ipython-magic


    【解决方案1】:

    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 变量(字符串表示形式)会按空格分隔,因此如果 myPythonVardatetime.datetimestr(myPythonVar)"2013-10-30 05:04:09.797507",则上述 bash 脚本将接收 3 个位置变量,前两个值为2013-10-3005: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 手册页。

    【讨论】:

      【解决方案2】:

      要在使用语法!<some command> 运行的bash 命令中包含python 变量,您可以使用{<variable>},如下所示:

      In [1]: for i in range(3):
         ...:     !echo {i+1}
         ...:     
      1
      2
      3
      

      虽然这与 OP 的要求略有不同,但它在执行脚本任务时密切相关且有用。 This post 有更多关于在 IPython 和 Jupyter 笔记本中使用 shell 命令的精彩技巧和示例。

      【讨论】:

      • 谢谢@awallllllll,刚刚替换了链接。
      • 这太好了,谢谢。看起来很 hacky,但我认为这是 jupyter notebooks 的全部目的。
      • 绝对不会猜到你可以随便使用!。你甚至可以n = !echo {i + 1}
      【解决方案3】:

      一个问题是,如果您要提供给 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 魔法正在寻找} 并且并不关心它。
      【解决方案4】:

      如果像我这样的人最终在这里寻找如何在使用! 运行命令时使用 Python 变量,只需为变量添加前缀$ 就可以了:

      !echo $foobar
      

      【讨论】:

        【解决方案5】:

        如果您需要向 bash 脚本传递除简单变量之外的其他内容,请注意一个变化:

        %%bash -s $dict['key1'] $dict['key2'] $dict['key3']
        

        出现了可怕的错误,但是

        %%bash -s {dict['key1']} {dict['key2']} {dict['key3']}
        

        效果很好。

        【讨论】:

          【解决方案6】:

          如果你愿意定义一个新的魔法,你可以使用 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}
          

          【讨论】:

            【解决方案7】:

            不,%%script 魔法是自动生成的,不会进行任何魔法进程间数据通信。 (%%R 的情况并非如此,但它在其自己的班级中是一个单独的魔法,R peoples 会格外小心)

            但是编写自己的魔法并不难。

            【讨论】:

            • 您的意思是像%%bash -c 'myvar=$MyPythonVar bash',然后可能是单元格下一行的echo $myvar?这行得通...
            • 所以..你有什么想法?如果%%bash .. 单元格没有其他内容,它会抱怨,如果我把ls 放在那里,操作系统会返回/bin/echo: /bin/echo: cannot execute binary file(至少在我的mac 上-但我认为ubuntu 做了类似的事情)
            • 啊抱歉,我读得太快了,虽然你写的东西有效。查看代码,bash 魔术不支持 {..} 语法,除了第一行。所以你需要自己写。
            • 好的。我找到了几种使用第一行的方法(答案如下)。我想写一个 %% 魔法来做得更好可能会更好 - 也许像 #%%exppose myPythonVar 这样的特殊 cmets 然后当你看到 $myPythonVar 或其他东西时将它的值替换到脚本中......也许有一天我会试一试(:
            • 在当前的 jupyter 中,我上面提出的方法似乎不起作用 - 无法从 %%bash 单元格的第一行访问 python 变量。 @Matt 你能确认一下吗?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-04-23
            • 2013-09-23
            • 1970-01-01
            • 2014-07-26
            • 2015-06-22
            • 2011-03-20
            • 1970-01-01
            相关资源
            最近更新 更多