2013-11-25 12 views
23

Interactive Python (ipython) è semplicemente fantastico, specialmente quando si mettono insieme le cose insieme ... e lo fa in modo che sia facile tornare indietro.ipynb importa un altro file ipynb

Tuttavia, ciò che sembra interessante è il caso di utilizzo di più taccuini ipython (file ipynb). Apparentemente sembra che un notebook NON abbia una relazione con altri notebook, il che ha senso, tranne che mi piacerebbe importare altri file ipynb.

L'unica soluzione che vedo è la conversione dei file * .ipynb in file * .py, che possono quindi essere importati nel mio notebook. Avere un file contiene tutto in un progetto è un po 'strano, specialmente se voglio davvero spingere per il riutilizzo del codice (non è un principio fondamentale di Python?).

Mi manca qualcosa? Questo non è un caso d'uso supportato di taccuini ipython? C'è un'altra soluzione che posso usare per importare un file ipynb in un altro notebook? Mi piacerebbe continuare a utilizzare ipynb, ma è davvero rovinare il mio flusso di lavoro in questo momento :(

+0

Eventuali duplicati: http://stackoverflow.com/questions/19082397/including-a-notebook-in-another-notebook-in-ipython –

+1

Si può avviare il server notebook con '--script' per salvare le copie .py dei tuoi taccuini. In IPython 2.0, potrai '% run' un notebook. Stiamo ancora elaborando meccanismi migliori per il riutilizzo del codice. –

+0

https://stackoverflow.com/q/20186344/478206, https://stackoverflow.com/q/19082397/478206 e https://stackoverflow.com/q/19564625/478206 fanno tutti la stessa domanda. –

risposta

14

This example mostra come importare i notebook ipython come moduli senza esportare duplicati come script.

+0

Fantastico. Grazie mille ... Ho cercato una risposta su questo per circa 4 ore e non ho potuto trovare nulla! –

+0

Esistono modi migliori per farlo a causa della domanda? Mi sento come importare altri notebook potrebbe essere più di un caso d'uso per Jupyter .. – user1496984

+0

Il link che hai dato è "404: Non trovato". Qualcuno ha un link simile (o aggiornamento)? Grazie ! – probaPerception

0

Il problema è che un notebook non è un semplice file python I passaggi per importare il file .ipynb sono delineati nel seguente: Importing notebook

Sto incollando il codice, quindi se ne hai bisogno ... puoi semplicemente fare una rapida copia e incolla. che alla fine ho la dichiarazione import primes. Dovrai cambiare ovviamente, il nome del mio file è primes.ipynb. puntualizza puoi usare il contenuto all'interno di quel file come faresti regolarmente.

Vorrei che ci fosse un metodo più semplice, ma questo è direttamente dai documenti.
Nota: sto usando jupyter non ipython.

import io, os, sys, types 
from IPython import get_ipython 
from nbformat import current 
from IPython.core.interactiveshell import InteractiveShell 


def find_notebook(fullname, path=None): 
    """find a notebook, given its fully qualified name and an optional path 

    This turns "foo.bar" into "foo/bar.ipynb" 
    and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar 
    does not exist. 
    """ 
    name = fullname.rsplit('.', 1)[-1] 
    if not path: 
     path = [''] 
    for d in path: 
     nb_path = os.path.join(d, name + ".ipynb") 
     if os.path.isfile(nb_path): 
      return nb_path 
     # let import Notebook_Name find "Notebook Name.ipynb" 
     nb_path = nb_path.replace("_", " ") 
     if os.path.isfile(nb_path): 
      return nb_path 


class NotebookLoader(object): 
    """Module Loader for Jupyter Notebooks""" 
    def __init__(self, path=None): 
     self.shell = InteractiveShell.instance() 
     self.path = path 

    def load_module(self, fullname): 
     """import a notebook as a module""" 
     path = find_notebook(fullname, self.path) 

     print ("importing Jupyter notebook from %s" % path) 

     # load the notebook object 
     with io.open(path, 'r', encoding='utf-8') as f: 
      nb = current.read(f, 'json') 


     # create the module and add it to sys.modules 
     # if name in sys.modules: 
     # return sys.modules[name] 
     mod = types.ModuleType(fullname) 
     mod.__file__ = path 
     mod.__loader__ = self 
     mod.__dict__['get_ipython'] = get_ipython 
     sys.modules[fullname] = mod 

     # extra work to ensure that magics that would affect the user_ns 
     # actually affect the notebook module's ns 
     save_user_ns = self.shell.user_ns 
     self.shell.user_ns = mod.__dict__ 

     try: 
     for cell in nb.worksheets[0].cells: 
      if cell.cell_type == 'code' and cell.language == 'python': 
       # transform the input to executable Python 
       code = self.shell.input_transformer_manager.transform_cell(cell.input) 
       # run the code in themodule 
       exec(code, mod.__dict__) 
     finally: 
      self.shell.user_ns = save_user_ns 
     return mod 


class NotebookFinder(object): 
    """Module finder that locates Jupyter Notebooks""" 
    def __init__(self): 
     self.loaders = {} 

    def find_module(self, fullname, path=None): 
     nb_path = find_notebook(fullname, path) 
     if not nb_path: 
      return 

     key = path 
     if path: 
      # lists aren't hashable 
      key = os.path.sep.join(path) 

     if key not in self.loaders: 
      self.loaders[key] = NotebookLoader(path) 
     return self.loaders[key] 

sys.meta_path.append(NotebookFinder()) 

import primes 
0

Non c'è alcun problema con Jupyter con i moduli Python .py esistenti o nuovi. Con Jupyter in esecuzione, è sufficiente attivare Spyder (o qualsiasi editor di tua scelta) per creare/modificare le definizioni della classe del modulo in un file .py, quindi importare i moduli in Jupyter.

Una cosa che rende questo davvero perfetto è l'utilizzo dell'estensione magica autoreload. Potete vedere la documentazione per autoreload qui:

http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html

Ecco il codice per ricaricare automaticamente il modulo in qualsiasi momento è stato modificato:

# autoreload sets up auto reloading of modified .py modules 
import autoreload 
%load_ext autoreload 
%autoreload 2 

Nota che ho provato il codice di cui in una prima rispondere per simulare il caricamento di file .ipynb come moduli e farlo funzionare, ma si strozza quando si apportano modifiche al file .ipynb. Sembra che sia necessario riavviare l'ambiente di sviluppo Jupyter per ricaricare il .ipynb "module", che non era accettabile dal momento che sto apportando molte modifiche al mio codice.

1

I commenti sopra riportati sono molto utili ma sono un po 'difficili da implementare. Di seguito è possibile provare, ho anche provato e ha funzionato:

  1. Scaricare quel file dal blocco note in formato PY (questa opzione è disponibile nella scheda File).
  2. Ora copia il file scaricato nella directory di lavoro di Jupyter Notebook
  3. Ora sei pronto per usarlo. Basta importare file .PY nel file ipynb
+0

hmm ... Ho convertito il file callee.ipync nel file callee.py, quindi ho caricato il file callee.py sul notebook nella stessa cartella con caller.ipync e il chiamante in.ipync Ho appena scritto 'import callee', non potevo funzionare. –

+0

p.s. il IPython è la versione: 5.1.0. –

+0

Ci scusiamo per il falso allarme. In questo modo funziona bene. –

36

E 'davvero semplice nella più recente Jupyter:

%run 'MyOtherNotebook.ipynb' 
+2

% run MyOtherNotebook.ipynb ha fatto il lavoro per me. (no '') –

+0

Attenzione, questo metodo eseguirà completamente il blocco appunti del bambino. È possibile aggiungere un controllo '__name__ == '__main__' e '__file__' non in globals()' per verificare se ci si trova nel blocco appunti figlio. (da https://blog.sicara.com/present-data-science-results-jupyter-notebook-import-into-another-108433bc8505) –

+0

Questo non funziona per me. Ottengo il seguente: 'NameError Traceback (chiamata più recente scorso) C: \ Dev \ Studio \ python \ interpret_basics \ nursery_utils.IPYNB in ​​() {3 4 "cell_type": "codice", - ---> 5 "execution_count": null, 6 "metadati": { 7 "collapsed": true NameError: nome 'null' non definito ' – julianhatwell

0

Si prega di assicurarsi che anche si aggiunge un file __init__.py nel pacchetto in cui tutti gli altri file .ipynb si trovano.

Questo è in aggiunta al collegamento nbviewer che minrk e syi fornito sopra.

Ho anche avuto qualche problema simile e poi ho scritto la soluzione così come un link al mio cartella sul disco google pubblico che ha un esempio funzionante :)

mio StackOverflow post con passo dopo passo la sperimentazione e soluzione:

Jupyter Notebook: Import .ipynb file and access it's method in other .ipynb file giving error

Spero che questo aiuti anche gli altri. Grazie a tutti!

0

Se si desidera importare A.ipynb da B.ipynb scrivere

import import_ipynb 
import A 

in B.ipynb.

Il modulo import_ipynb che ho creato è installato tramite pip:

pip install import_ipynb 

E 'solo un file e si attiene strettamente alla official howto sul sito jupyter.

PS Supporta anche le cose come from A import foo, from A import * ecc