ipynb importa un altro file ipynb


99

Interactive Python (ipython) è semplicemente fantastico, soprattutto perché stai mettendo insieme le cose al volo ... e lo fa in modo tale che sia facile tornare indietro.

Tuttavia, ciò che sembra essere interessante è il caso d'uso di avere più notebook ipython (file ipynb). Apparentemente sembra che un notebook NON dovrebbe avere una relazione con altri notebook, il che ha senso, tranne per il fatto che mi piacerebbe importare altri file ipynb.

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

Mi sto perdendo qualcosa? Non è questo un caso d'uso supportato dei notebook ipython? C'è un'altra soluzione che posso utilizzare per questa importazione di un file ipynb in un altro notebook? Mi piacerebbe continuare a usare ipynb, ma in questo momento sta davvero rovinando il mio flusso di lavoro :(



2
È possibile avviare il server notebook con --scriptper salvare copie .py dei blocchi appunti. In IPython 2.0, sarai in grado di utilizzare %runun notebook. Stiamo ancora elaborando meccanismi migliori per il riutilizzo del codice.
Thomas K

1
Questo esempio mostra come importare notebook IPython come moduli senza esportare duplicati come script.
visone

Risposte:


133

È davvero semplice nel nuovo Jupyter:

%run MyOtherNotebook.ipynb

5
% run MyOtherNotebook.ipynb ha fatto il lavoro per me. (no '')
Florian H

6
Fai attenzione, questo metodo eseguirà completamente il notebook figlio. Puoi aggiungere un segno __name__ == '__main__' and '__file__' not in globals()di spunta per verificare se sei nel blocco note figlio. (da blog.sicara.com/… )
Flavian Hautbois

8
% run "MyOtherNotebook.ipynb" ERRORE: root: file u'MyOtherNotebook.ipynb.py'non trovato.
user3673

1
@ Kocur4d Grazie per il fissaggio! È interessante notare che ha funzionato per me (con virgolette) quando l'ho provato, ma gli esempi nella documentazione non hanno virgolette.
johndodo

3
se qualcuno si imbatte in questo, puoi anche usare il percorso completo come% run "/path/to/my/file/notebook.ipynb"
Jeremie,

37

Se vuoi importare A.ipynbin B.ipynbscrittura

import import_ipynb
import A

in B.ipynb.

Il import_ipynbmodulo che ho creato viene installato tramite pip:

pip install import_ipynb

È solo un file e aderisce strettamente all'howto ufficiale sul sito jupyter.

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


Anche @Crash pip install import-ipynbfunziona e installa lo stesso pacchetto, ma poiché python non ti consente di scrivere import import-ipynbe considerando che è solo un file, mi pip install import_ipynbsembra più coerente.
axil

3
C'è qualche differenza tra import nbimportere import import_ipynb?
Fractale

1
Questo non funziona affatto nel mio Jupyter con Python 3
Sebastialonso

@Sebastialonso Cosa non funziona esattamente? Descrivi cosa fai e quali messaggi di errore vedi. Idealmente apri un ticket su GitHub.
ascia

@axil Ho lo stesso errore in cui non funziona per me in Py3. Mi dà il seguente errore - ModuleNotFoundError: Nessun modulo denominato 'A' PS: A.ipynb esiste nella stessa cartella
Soman Dubey

11

Correre

!pip install ipynb

e quindi importa l'altro blocco note come

from ipynb.fs.full.<notebook_name> import *

o

from ipynb.fs.full.<notebook_name> import <function_name>

Assicurati che tutti i taccuini siano nella stessa directory.

Modifica 1: puoi vedere la documentazione ufficiale qui: https://ipynb.readthedocs.io/en/stable/

Inoltre, se desideri importare solo definizioni di classi e funzioni da un notebook (e non le istruzioni di primo livello), puoi usare al ipynb.fs.defsposto di ipynb.fs.full. Verrà valutata anche l'assegnazione completa di variabili maiuscole.


E se il nome del mio file contiene spazi bianchi?
Sameh

Si consiglia di non mantenere spazi
vuoti

2
Notare che in entrambi i casi descritti, il blocco note importato viene eseguito per intero. Il ipynbpacchetto supporta anche solo l'esecuzione parziale delle definizioni. È un pacchetto ufficiale di IPyhton, quindi credo che questa dovrebbe essere la risposta accettata.
amka66

Può importare taccuini all'interno di una cartella? ad esempioMyFolder/book.ipynb
bone225

Sembrava buono ma cade quando incontra ad esempio% matplotlib inline ....
jtlz2

7

Installa ipynb dal prompt dei comandi

pip install import-ipynb

Importa nel file del tuo taccuino

import import_ipynb

Ora usa il normale comando di importazione per importare il tuo file

import MyOtherNotebook

Risposta più semplice ma esplicativa. Grazie!
Il povero ebreo

questo richiede che la directory, dove si trova il notebook da importare, abbia un init .py?
Luk Aron

3

Puoi usare import nbimporteralloraimport notebookName


+1, nbimporter funziona come un fascino per me, inoltre può essere installato utilizzando conda:conda install -c conda-forge importnb
Zuku

2

I commenti sopra citati sono molto utili ma un po 'difficili da implementare. Di seguito i passaggi che puoi provare, l'ho provato anche e ha funzionato:

  1. Scarica quel file dal tuo taccuino in formato file PY (puoi trovare questa opzione nella scheda File).
  2. Ora copia il file scaricato nella directory di lavoro di Jupyter Notebook
  3. Ora sei pronto per usarlo. Basta importare il file .PY nel file ipynb

hmm ... ho convertito il file callee.ipync in callee.py, quindi ho caricato il file callee.py sul notebook nella stessa cartella con caller.ipync, e in caller.ipync ho appena scritto import callee, semplicemente non potevo lavoro.
Elsa Lin

ps l'IPython è la versione: 5.1.0.
Elsa Lin,

1

Il problema è che un notebook non è un semplice file Python. I passaggi per importare il .ipynbfile sono descritti di seguito: Importazione del blocco appunti

Sto incollando il codice, quindi se ne hai bisogno ... puoi semplicemente fare un rapido copia e incolla. Si noti che alla fine ho la import primesdichiarazione. Ovviamente dovrai cambiarlo. Il nome del mio file è primes.ipynb. Da questo punto in poi puoi utilizzare 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

1

Non ci sono problemi nell'usare Jupyter con moduli Python .py esistenti o nuovi. Con Jupyter in esecuzione, avvia semplicemente Spyder (o qualsiasi editor di tua scelta) per creare / modificare le definizioni delle classi dei moduli in un file .py, quindi importa i moduli in base alle necessità in Jupyter.

Una cosa che rende tutto ciò davvero semplice è l'utilizzo dell'estensione magica di caricamento automatico. Puoi vedere la documentazione per il caricamento automatico qui:

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

Ecco il codice per ricaricare automaticamente il modulo ogni volta che è stato modificato:

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

Si noti che ho provato il codice menzionato in una risposta precedente per simulare il caricamento di file .ipynb come moduli e l'ho fatto funzionare, ma si blocca quando si apportano modifiche al file .ipynb. Sembra che sia necessario riavviare l'ambiente di sviluppo Jupyter per ricaricare il "modulo" .ipynb, il che non era accettabile perché sto apportando molte modifiche al mio codice.


0

Assicurati di aggiungere anche un __init__.pyfile nel pacchetto in cui si trovano tutti gli altri file .ipynb.

Questo è in aggiunta al collegamento nbviewer minrke syifornito sopra.

Ho anche avuto qualche problema simile e poi ho scritto la soluzione e un collegamento alla mia cartella pubblica di Google Drive che ha un esempio funzionante :)

Il mio post Stackoverflow con sperimentazione e soluzione passo passo:

Notebook Jupyter: importa il file .ipynb e accedi al suo metodo in un altro file .ipynb che dà errore

Spero che questo possa aiutare anche gli altri. Ringrazia tutti!


0

% run YourNotebookfile.ipynb funziona bene;

se vuoi importare un modulo specifico, aggiungi semplicemente il comando di importazione dopo ipynb cioè YourNotebookfile.ipynb con def Add ()

allora puoi semplicemente usarlo

%run YourNotebookfile.ipynb import Add
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.