ipynb importar outro arquivo ipynb


99

O Python interativo (ipython) é simplesmente incrível, especialmente porque você está juntando as peças na hora ... e faz isso de uma maneira que é fácil voltar atrás.

No entanto, o que parece ser interessante é o caso de uso de vários notebooks ipython (arquivos ipynb). Aparentemente, parece que um notebook NÃO deve ter um relacionamento com outros notebooks, o que faz sentido, exceto que eu adoraria importar outros arquivos ipynb.

A única solução alternativa que vejo é converter meus arquivos * .ipynb em arquivos * .py, que podem ser importados para meu notebook. Ter um arquivo contendo tudo em um projeto é um pouco estranho, especialmente se eu quiser realmente forçar a reutilização de código (isso não é um princípio básico do python?).

Estou esquecendo de algo? Este não é um caso de uso compatível com notebooks ipython? Existe outra solução que posso usar para esta importação de um arquivo ipynb para outro notebook? Adoraria continuar usando o ipynb, mas ele está realmente atrapalhando meu fluxo de trabalho agora :(



2
Você pode iniciar o servidor do notebook --scriptpara salvar cópias .py de seus notebooks. No IPython 2.0, você poderá usar %runum notebook. Ainda estamos trabalhando em mecanismos melhores para reutilização de código.
Thomas K

1
Este exemplo mostra como importar notebooks IPython como módulos sem exportar duplicatas como scripts.
minrk

Respostas:


133

É muito simples no Jupyter mais recente:

%run MyOtherNotebook.ipynb

5
% run MyOtherNotebook.ipynb fez o trabalho para mim. (sem '')
Florian H

6
Tenha cuidado, esse método executará completamente o notebook filho. Você pode adicionar uma marca __name__ == '__main__' and '__file__' not in globals()para verificar se está no bloco de notas da criança. (de blog.sicara.com/… )
Flavian Hautbois

8
% run 'MyOtherNotebook.ipynb' ERRO: root: Arquivo u'MyOtherNotebook.ipynb.py'não encontrado.
user3673

1
@ Kocur4d Obrigado por corrigir! Curiosamente, funcionou para mim (com aspas) quando tentei, mas os exemplos na documentação não têm aspas.
johndodo

3
se alguém encontrar isso, você também pode usar o caminho completo como% run "/path/to/my/file/notebook.ipynb"
Jeremie

37

Se você deseja importar A.ipynbpor B.ipynbescrito

import import_ipynb
import A

no B.ipynb.

O import_ipynbmódulo que criei é instalado via pip:

pip install import_ipynb

É apenas um arquivo e segue estritamente o howto oficial do site jupyter.

PS Também suporta coisas como from A import foo, from A import *etc


@Crash pip install import-ipynbtambém funciona e instala exatamente o mesmo pacote, mas como o python não permite que você escreva import import-ipynbe considerando que é apenas um arquivo, pip install import_ipynbparece mais consistente para mim.
axila

3
Existe alguma diferença entre import nbimportere import import_ipynb?
Fractale

1
Isso não funciona de jeito nenhum no meu Jupyter com Python 3
Sebastialonso

@Sebastialonso O que exatamente não funciona? Descreva o que você faz e quais mensagens de erro você vê. O ideal é abrir um tíquete no github.
axil

@axil Eu tenho o mesmo erro que não funciona para mim no Py3. Isso me dá o seguinte erro - ModuleNotFoundError: Nenhum módulo chamado 'A' PS: A.ipynb existe na mesma pasta
Soman Dubey

11

Corre

!pip install ipynb

e, em seguida, importe o outro bloco de notas como

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

ou

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

Certifique-se de que todos os blocos de notas estejam no mesmo diretório.

Edição 1: Você pode ver a documentação oficial aqui - https://ipynb.readthedocs.io/en/stable/

Além disso, se desejar importar apenas as definições de classe e função de um bloco de notas (e não as instruções de nível superior), você pode usar em ipynb.fs.defsvez de ipynb.fs.full. A atribuição completa de variáveis ​​em maiúsculas também será avaliada.


E se meu nome de arquivo contiver um espaço em branco?
Sameh,

É aconselhável não manter nenhum espaço em branco no nome do arquivo
Malgo

2
Observe que em ambos os casos descritos, o notebook importado é executado por completo. O ipynbpacote também oferece suporte à execução parcial de definições apenas. É um pacote oficial da IPyhton, então acredito que essa deve ser a resposta aceita.
amka66

Isso pode importar blocos de notas dentro de uma pasta? por exemploMyFolder/book.ipynb
bones225

Isso parecia bom, mas falha quando encontra, por exemplo,% matplotlib inline ....
jtlz2

7

Instale o ipynb a partir do seu prompt de comando

pip install import-ipynb

Importar em seu arquivo de notebook

import import_ipynb

Agora use o comando de importação regular para importar seu arquivo

import MyOtherNotebook

Resposta mais simples, mas explicativa. Obrigado!
The Poor Jew

isso requer que o diretório onde está localizado o bloco de notas a ser importado tenha um init .py?
Luk Aron

3

Você pode usar import nbimporterentãoimport notebookName


+1, nbimporter funciona perfeitamente para mim, também pode ser instalado usando conda:conda install -c conda-forge importnb
Zuku

2

Os comentários mencionados acima são muito úteis, mas são um pouco difíceis de implementar. Abaixo os passos que você pode tentar, eu também tentei e funcionou:

  1. Baixe esse arquivo do seu notebook no formato de arquivo PY (você pode encontrar essa opção na guia Arquivo).
  2. Agora copie o arquivo baixado para o diretório de trabalho do Jupyter Notebook
  3. Agora você está pronto para usá-lo. Basta importar o arquivo .PY para o arquivo ipynb

hmm ... Converti o arquivo callee.ipync para callee.py e carreguei o arquivo callee.py no bloco de notas na mesma pasta com caller.ipync, e o em caller.ipync acabei de escrever import callee, mas não consegui trabalhos.
Elsa Lin

ps o IPython é a versão: 5.1.0.
Elsa Lin

1

O problema é que um notebook não é um arquivo python simples. As etapas para importar o .ipynbarquivo são descritas a seguir: Importando notebook

Estou colando o código, então se você precisar ... pode apenas copiar e colar rapidamente. Observe que no final eu tenho a import primesdeclaração. Você terá que mudar isso, é claro. O nome do meu arquivo é primes.ipynb. Deste ponto em diante, você pode usar o conteúdo desse arquivo como faria regularmente.

Gostaria que houvesse um método mais simples, mas isso veio direto dos documentos.
Nota: Estou usando o jupyter, não o 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

Não há nenhum problema em usar o Jupyter com módulos .py Python novos ou existentes. Com o Jupyter em execução, basta iniciar o Spyder (ou qualquer editor de sua escolha) para construir / modificar suas definições de classe de módulo em um arquivo .py e, em seguida, apenas importar os módulos conforme necessário para o Jupyter.

Uma coisa que torna isso realmente fácil é usar a extensão mágica autoreload. Você pode ver a documentação do autoreload aqui:

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

Aqui está o código para recarregar automaticamente o módulo sempre que for modificado:

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

Observe que tentei o código mencionado em uma resposta anterior para simular o carregamento de arquivos .ipynb como módulos e fiz com que funcionasse, mas ele engasga quando você faz alterações no arquivo .ipynb. Parece que você precisa reiniciar o ambiente de desenvolvimento Jupyter para recarregar o 'módulo' .ipynb, o que não era aceitável para mim, pois estou fazendo muitas alterações em meu código.


0

Certifique-se de adicionar também um __init__.py arquivo no pacote onde todos os outros arquivos .ipynb estão localizados.

Esta é, para além do link nbviewer que minrke syifornecido acima.

Eu também tive alguns problemas semelhantes e então escrevi a solução, bem como um link para a minha pasta pública do Google Drive que tem um exemplo funcional :)

Minha postagem Stackoverflow com experimentação e solução passo a passo:

Jupyter Notebook: Importe o arquivo .ipynb e acesse seu método em outro arquivo .ipynb com erro

Espero que isso ajude outras pessoas também. Obrigado a todos!


0

% run YourNotebookfile.ipynb está funcionando bem;

se você deseja importar um módulo específico, basta adicionar o comando de importação após o ipynb, ou seja, YourNotebookfile.ipynb tendo def Add ()

então você pode apenas usá-lo

%run YourNotebookfile.ipynb import Add
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.