102

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
  • As the command is Equivalent to $ python file args, so I guess It's not possible. Commented Jan 18, 2013 at 23:26

6 Answers 6

168

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'] 
Sign up to request clarification or add additional context in comments.

6 Comments

Just wanted to mention that this also works very nicely when just running arbitrary shell commands using an exclamation mark (!) - see the official docs - ipython.org/ipython-doc/rel-0.10.2/html/interactive/…
@minrk Just a simple question what is the difference between variable and expression. Is a dictionary variable a expression? I ask because following your example I had to use the fancy string formatting to expand the dictionary but failed when I used $ instead. I thought lists, dictionaries etc. are all variable types.
I tried that on %%html cell magic and it didn't work. Is there a different syntax for cell magics as opposed to line magics?
As of version 7.3, some magics opt out of this expansion, time, timeit, debug and prun. github.com/ipython/ipython/pull/11516
If you want to pass a list of arguments: %run "my_script.py" {' '.join(map(str, my_arguments_list))} Note that you'll have to retransform the strings to whatever you need on the script's side.
|
14

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.

1 Comment

While this isn't the best way to do it, it answered another question of mine, which was how to execute ipython magic commands within a python console (as in, while using spyder)
5

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

%run "$filename" 

Comments

1

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.

Comments

1

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.

1 Comment

Nice code... Thanks for pointing out to get_ipython().ev(...), very useful!
1

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}") 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.