propias - Cómo pasar una variable a la función mágica ''ejecutar'' en IPython
lista de funciones de python (3)
IPython expande variables con $name
, bash-style. Esto es cierto para todas las magias , no solo para %run
.
Entonces lo harías:
In [1]: filename = "myscript.py"
In [2]: %run $filename
[''myscript.py'']
myscript.py contiene:
import sys
print(sys.argv)
Mediante el elegante formato de cadena de Python, incluso puede poner expresiones dentro de {}
:
In [3]: args = ["arg1", "arg2"]
In [4]: %run $filename {args[0]} {args[1][-2:]}
[''myscript.py'', ''arg1'', ''g2'']
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 ejecutar ''name.py''
, que no es lo que quiero hacer.
¿Hay una forma general de convertir las variables en cadenas?
Algo como lo siguiente:
In[3]: %run %name%
Parece que esto es imposible con la función incorporada %run
magia de %run
. Sin embargo, tu pregunta me llevó a un agujero de conejo, y quería ver lo fácil que sería hacer algo similar. Al final, parece algo inútil hacer todo este esfuerzo para crear otra función mágica que solo use execfile()
. Tal vez esto sea de alguna utilidad para alguien, en alguna parte.
# 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 de esta manera:
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 hack enorme y probablemente un desperdicio. En ese sentido, me pregunto si hay una forma de que el nombre vinculado al objeto Macro se use como el nombre real de la macro. Veremos eso.
Use get_ipython()
para obtener una referencia al InteractiveShell actual, luego llame al método magic()
:
In [1]: ipy = get_ipython()
In [2]: ipy.magic("run foo.py")
ERROR: File `u''foo.py''` not found.
Editar Ver la respuesta de Minrk : esa es una forma mucho mejor de hacerlo.