Cómo pasar una variable a la función mágica ´run´ en IPython


81

Quiero hacer algo como lo siguiente:

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

In[2]: %run name

pero esto realmente intenta funcionar 'name.py', que no es lo que quiero hacer.

¿Existe una forma general de convertir variables en cadenas?

Algo parecido a lo siguiente:

In[3]: %run %name%

Como el comando es equivalente a $ python file args, supongo que no es posible.
Ashwini Chaudhary

Respuestas:


130

IPython expande las variables con $name, bash-style. Esto es cierto para todas las magias , no solo %run.

Entonces harías:

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

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

myscript.py contiene:

import sys
print(sys.argv)

A través del elegante formato de cadena de Python, incluso puede poner expresiones dentro {}:

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

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

5
Solo quería mencionar que esto también funciona muy bien cuando solo se ejecutan comandos de shell arbitrarios con un signo de exclamación (!) - vea los documentos oficiales - ipython.org/ipython-doc/rel-0.10.2/html/interactive/…
yoniLavi

@minrk Solo una simple pregunta cuál es la diferencia entre variable y expresión. ¿Es una variable de diccionario una expresión? Lo pregunto porque, siguiendo su ejemplo, tuve que usar el elegante formato de cadena para expandir el diccionario, pero fallé cuando usé $ en su lugar. Pensé que las listas, diccionarios, etc. son todos tipos de variables.
Stephen Jacob

Probé eso con %%htmlmagia celular y no funcionó. ¿Existe una sintaxis diferente para la magia celular a diferencia de la magia lineal?
MROB

A partir de la versión 7.3, algunos magicsde exclusión de esta expansión, time, timeit, debugy prun. github.com/ipython/ipython/pull/11516
hpaulj

11

Úselo get_ipython()para obtener una referencia al InteractiveShell actual , luego llame al magic()método:

In [1]: ipy = get_ipython()

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

Editar Vea la respuesta de minrk : esa es una manera mucho mejor de hacerlo.


1
Si bien esta no es la mejor manera de hacerlo, respondió otra pregunta mía, que era cómo ejecutar comandos mágicos de ipython dentro de una consola de Python (como en, mientras se usa Spyder)
stuppie

1

Parece que esto es imposible con la %runfunción mágica incorporada. Sin embargo, tu pregunta me llevó a la madriguera de un conejo y quería ver qué tan fácil sería hacer algo similar. Al final, parece un tanto inútil hacer todo este esfuerzo para crear otra función mágica que acaba de usar execfile(). Quizás esto sea de alguna utilidad para alguien, en algún lugar.

# 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

Usando este par de clases, (y dado un script de Python tester.py) es posible crear y usar una variable "macro" con la función mágica "my_run" recién creada así:

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'

Sí, este es un truco enorme y probablemente derrochador. En ese sentido, me pregunto si hay una manera de que el nombre vinculado al objeto Macro se use como el nombre real de la macro. Lo investigaremos.


1

En caso de que haya espacio en el argumento, por ejemplo, nombre de archivo, es mejor usar esto:

%run "$filename"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.