Je veux faire quelque chose comme ceci:
In[1]: name = 'long_name_to_type_every_now_and_then.py'
In[2]: %run name
mais cela essaie en fait d'exécuter 'name.py'
, ce qui n'est pas ce que je veux faire.
Existe-t-il un moyen général de transformer des variables en chaînes?
Quelque chose comme ceci:
In[3]: %run %name%
IPython étend les variables avec $name
, style bash. Cela est vrai pour toutes les magies, pas seulement %run
.
Vous feriez donc:
In [1]: filename = "myscript.py"
In [2]: %run $filename
['myscript.py']
myscript.py contient:
import sys
print(sys.argv)
Grâce au formatage de chaînes sophistiqué de Python, vous pouvez même mettre des expressions à l'intérieur de {}
:
In [3]: args = ["arg1", "arg2"]
In [4]: %run $filename {args[0]} {args[1][-2:]}
['myscript.py', 'arg1', 'g2']
Utilisez get_ipython()
pour obtenir une référence au courant InteractiveShell , puis appelez la méthode magic()
:
In [1]: ipy = get_ipython()
In [2]: ipy.magic("run foo.py")
ERROR: File `u'foo.py'` not found.
Modifier Voir réponse de minrk - c'est une bien meilleure façon de le faire.
Il semble que cela soit impossible avec la fonction magique %run
Intégrée. Votre question m'a conduit dans un terrier de lapin, cependant, et je voulais voir à quel point il serait facile de faire quelque chose de similaire. À la fin, il semble quelque peu inutile d'aller à tous ces efforts pour créer une autre fonction magique qui utilise simplement execfile()
. Peut-être que cela sera utile à quelqu'un, quelque part.
# 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
En utilisant cette paire de classes, (et étant donné un script python tester.py
)), Il est possible de créer et d'utiliser une variable "macro" avec la fonction magique "my_run" nouvellement créée comme ceci :
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'
Oui, c'est un hack énorme et probablement inutile. Dans cette veine, je me demande s'il existe un moyen d'utiliser le nom lié à l'objet Macro comme nom réel de la macro. Va examiner cela.