2016-03-20 9 views
5

Ich möchte ändern, wie IPython import-Fehler standardmäßig behandelt. Wenn ich etwas in der IPython-Shell prototype, vergesse ich normalerweise, zuerst os, re oder was auch immer ich brauche zu importieren. Die ersten paar Anweisungen folgen oft dieses Muster:Make IPython Import Was ich meine

In [1]: os.path.exists("~/myfile.txt") 
--------------------------------------------------------------------------- 
NameError         Traceback (most recent call last) 
<ipython-input-1-0ffb6014a804> in <module>() 
----> 1 os.path.exists("~/myfile.txt") 

NameError: name 'os' is not defined 

In [2]: import os 

In [3]: os.path.exists("~/myfile.txt") 
Out[3]: False 

Sicher, das ist meine Schuld für schlechte Gewohnheiten haben und sicher, in einem Skript oder echtes Programm, das Sinn macht, aber in der Schale Ich würde eher, dass IPython folgen dem DWIM-Prinzip, durch mindestens versucht zu importieren, was ich versuche zu verwenden.

In [1]: os.path.exists("~/myfile.txt") 
--------------------------------------------------------------------------- 
NameError         Traceback (most recent call last) 
<ipython-input-1-0ffb6014a804> in <module>() 
----> 1 os.path.exists("~/myfile.txt") 

NameError: name 'os' is not defined 

Catching this for you and trying to import "os" … success! 
Retrying … 
--------------------------------------------------------------------------- 
Out[1]: False 

Wenn dies mit einem Vanille-IPython nicht möglich ist, was habe ich zu tun, um diese Arbeit zu machen? Ist ein wrapper kernel der einfachste Weg vorwärts? Oder sollte dies direkt im Kern implementiert werden, mit einem magischen Befehl?

Hinweis, das ist anders als those kind of question wo jemand immer vordefinierte Module laden will. Ich nicht. Denn ich weiß nicht, was ich arbeiten werden, und ich will nicht alles (noch will ich halten die Liste der alles aktualisiert laden

Antwort

10

. HINWEIS: Dies ist jetzt wobei on Github gehalten. von dort die neuesten Version des Skripts herunterladen!

ich ein Skript entwickelt, die IPython der Ausnahme durch set_custom_exc Umgang bindet. Wenn es ein NameError ist, verwendet es einen regulären Ausdruck zu finden, was Modul Sie versuchen, und dann zu verwenden, Versuchen Sie es zu importieren.Sie führt dann die Funktion aus, die Sie erneut aufrufen wollten. Hier ist der Code:

import sys, IPython, colorama # <-- colorama must be "pip install"-ed 

colorama.init() 

def custom_exc(shell, etype, evalue, tb, tb_offset=None): 
    pre = colorama.Fore.CYAN + colorama.Style.BRIGHT + "AutoImport: " + colorama.Style.NORMAL + colorama.Fore.WHITE 
    if etype == NameError: 
     shell.showtraceback((etype, evalue, tb), tb_offset) # Show the normal traceback 
     import re 
     try: 
      # Get the name of the module you tried to import 
      results = re.match("name '(.*)' is not defined", str(evalue)) 
      name = results.group(1) 

      try: 
       __import__(name) 
      except: 
       print(pre + "{} isn't a module".format(name)) 
       return 

      # Import the module 
      IPython.get_ipython().run_code("import {}".format(name)) 
      print(pre + "Imported referenced module \"{}\", will retry".format(name)) 
     except Exception as e: 
      print(pre + "Attempted to import \"{}\" but an exception occured".format(name)) 

     try: 
      # Run the failed line again 
      res = IPython.get_ipython().run_cell(list(get_ipython().history_manager.get_range())[-1][-1]) 
     except Exception as e: 
      print(pre + "Another exception occured while retrying") 
      shell.showtraceback((type(e), e, None), None) 
    else: 
     shell.showtraceback((etype, evalue, tb), tb_offset=tb_offset) 

# Bind the function we created to IPython's exception handler 
IPython.get_ipython().set_custom_exc((Exception,), custom_exc) 

Sie können diesen Lauf automatisch, wenn Sie eine IPython Aufforderung starten, indem Sie es irgendwo speichern und dann eine Umgebungsvariable namens PYTHONSTARTUP auf diese Datei auf den Weg. Sie setzen anders Umgebungsvariablen je nach Betriebssystem (nicht vergessen, die Wege zu ändern):

  • Fenster: setx PYTHONSTARTUP C:\startup.py in Eingabeaufforderung
  • Mac/Linux (bash): Setzen Sie export PYTHONSTARTUP=$HOME/startup.py in Ihre ~/.bashrc

hier ist eine Demo des Skripts in Aktion:

Demo

+0

_Currently, dieses Skript infi nite-loops bei einigen Fehlern_ - Wenn der Import zu einer Namensfehler- und Bereinigungsroutine führt, wird der gleiche Import durchgeführt ... - Sie wissen bereits, was passiert. Sie müssen überprüfen, ob das Modul, das Sie importieren möchten, existiert. –

+0

@Rogalski Wie würde ich das tun? Ich weiß, 'pip' hat Methoden, um dies zu tun, aber jemand könnte etwas importieren, das auf ihrem lokalen Rechner ist. –

+0

Run: 'versuchen: importieren was auch immer außer ImportError: oops_failed_to_import_handle_it()'? –