How to pass a variable to magic ´run´ function in IPython

♀尐吖头ヾ 提交于 2019-12-28 04:58:04

问题


I want to do something like the following:

In[1]: name = 'long_name_to_type_every_now_and_then.py'

In[2]: %run name

but this actually tries to run 'name.py', which is not what I want to do.

Is there a general way to turn variables into strings?

Something like the following:

In[3]: %run %name%

回答1:


IPython expands variables with $name, bash-style. This is true for all magics, not just %run.

So you would do:

In [1]: filename = "myscript.py"

In [2]: %run $filename
['myscript.py']

myscript.py contains:

import sys
print(sys.argv)

Via Python's fancy string formatting, you can even put expressions inside {}:

In [3]: args = ["arg1", "arg2"]

In [4]: %run $filename {args[0]} {args[1][-2:]}
['myscript.py', 'arg1', 'g2']



回答2:


Use get_ipython() to get a reference to the current InteractiveShell, then call the magic() method:

In [1]: ipy = get_ipython()

In [2]: ipy.magic("run foo.py")
ERROR: File `u'foo.py'` not found.

Edit See minrk's answer — that's a much better way to do it.




回答3:


It seems this is impossible with the built-in %run magic function. Your question led me down a rabbit hole, though, and I wanted to see how easy it would be to do something similar. At the end, it seems somewhat pointless to go to all this effort to create another magic function that just uses execfile(). Maybe this will be of some use to someone, somewhere.

# custom_magics.py
from IPython.core.magic import register_line_magic, magics_class, line_magic, Magics

@magics_class
class StatefulMagics(Magics):
    def __init__(self, shell, data):
        super(StatefulMagics, self).__init__(shell)
        self.namespace = data

    @line_magic
    def my_run(self, line):
        if line[0] != "%":
            return "Not a variable in namespace"
        else:
            filename = self.namespace[line[1:]].split('.')[0]
            filename += ".py"
            execfile(filename)
        return line

class Macro(object):
    def __init__(self, name, value):
        self.name = name
        self._value = value
        ip = get_ipython()
        magics = StatefulMagics(ip, {name: value})
        ip.register_magics(magics)

    def value(self):
        return self._value

    def __repr__(self):
        return self.name

Using this pair of classes, (and given a python script tester.py) it's possible to create and use a "macro" variable with the newly created "my_run" magic function like so:

In [1]: from custom_magics import Macro

In [2]: Macro("somename", "tester.py")
Out[2]: somename

In [3]: %my_run %somename
I'm the test file and I'm running!
Out[3]: u'%somename'

Yes, this is a huge and probably wasteful hack. In that vein, I wonder if there's a way to have the name bound to the Macro object be used as the macro's actual name. Will look into that.




回答4:


In case there might be space in argument, e.g. filename, it is better to use this:

%run "$filename"


来源:https://stackoverflow.com/questions/14409167/how-to-pass-a-variable-to-magic-%c2%b4run%c2%b4-function-in-ipython

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!