Reputation: 2707
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%
Upvotes: 102
Views: 51489
Reputation: 5202
More generally, but lacking pretty formatting:
ipy = get_ipython()
ipy.run_cell_magic("spark", "", f"""
from_dt = "{start_date}"
to_dt = "{end_date}"
""")
effectively runs under a %%spark
magic. For single %
line magic:
ipy = get_ipython()
ipy.run_line_magic("sql", "", f"SELECT * FROM {table_name}")
Upvotes: 0
Reputation: 2028
If by 'variable' you mean a variable available in the user namespace, then I'd suggest to use get_ipython().ev(varname)
(docs) to get your variable in your function:
from __future__ import print_function
import argparse
import shlex
from IPython import get_ipython
from IPython.core.magic import register_cell_magic
@register_cell_magic
def magical(line, cell):
parser = argparse.ArgumentParser()
parser.add_argument("varname")
# using shlex to split the line in a sys.argv-like format
args = parser.parse_args(shlex.split(line))
ipython = get_ipython()
v = ipython.ev(args.varname)
# do whatever you want here
print(v)
This template above served me well - I used it to make a jinja2 cell magic that also prints to file whenever the cell is run.
Upvotes: 1
Reputation: 131
In case there might be space in argument, e.g. filename, it is better to use this:
%run "$filename"
Upvotes: 4
Reputation: 6207
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.
Upvotes: 1
Reputation: 154494
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.
Upvotes: 14
Reputation: 38598
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']
Upvotes: 167