Interaktywny Python (ipython) jest po prostu niesamowity, zwłaszcza, że układasz rzeczy w locie ... i robisz to w taki sposób, że łatwo jest wrócić.
Jednak to, co wydaje się interesujące, to przypadek użycia posiadania wielu notatników ipython (pliki ipynb). Wygląda na to, że notatnik NIE powinien mieć związku z innymi notatnikami, co ma sens, z wyjątkiem tego, że chciałbym zaimportować inne pliki ipynb.
Jedyne obejście, jakie widzę, to przekonwertowanie moich plików * .ipynb na pliki * .py, które następnie można zaimportować do mojego notatnika. Posiadanie jednego pliku zawierającego wszystko w projekcie jest trochę dziwne, zwłaszcza jeśli naprawdę chcę naciskać na ponowne użycie kodu (czy nie jest to podstawowa zasada Pythona?).
Czy coś mi brakuje? Czy to nie jest obsługiwany przypadek użycia notebooków ipython? Czy istnieje inne rozwiązanie, którego mogę użyć do tego importu pliku ipynb do innego notebooka? Chciałbym nadal używać ipynb, ale teraz naprawdę psuje mi to przepływ pracy :(
--script
aby zapisać kopie .py swoich notatników. W IPython 2.0 możesz mieć%run
notebooka. Wciąż pracujemy nad lepszymi mechanizmami ponownego wykorzystania kodu.Odpowiedzi:
W nowszym Jupyter jest to naprawdę proste:
źródło
__name__ == '__main__' and '__file__' not in globals()
aby sprawdzić, czy jesteś w notesie podrzędnym. (z blog.sicara.com/… )u'MyOtherNotebook.ipynb.py'
Nie znaleziono pliku .Jeśli chcesz importować
A.ipynb
wB.ipynb
zapisieimport import_ipynb import A
w
B.ipynb
.Utworzony
import_ipynb
przeze mnie moduł jest instalowany przez pip:To tylko jeden plik i jest ściśle zgodny z oficjalnym howto na stronie jupyter.
PS Obsługuje również takie rzeczy
from A import foo
,from A import *
etcźródło
pip install import-ipynb
również działa i instaluje ten sam pakiet, ale ponieważ Python nie pozwala ci pisaćimport import-ipynb
i biorąc pod uwagę, że jest to tylko jeden plik,pip install import_ipynb
wygląda dla mnie bardziej spójnie.import nbimporter
iimport import_ipynb
?Biegać
!pip install ipynb
a następnie zaimportuj drugi notatnik jako plik
from ipynb.fs.full.<notebook_name> import *
lub
from ipynb.fs.full.<notebook_name> import <function_name>
Upewnij się, że wszystkie notatniki znajdują się w tym samym katalogu.
Edycja 1: Możesz zobaczyć oficjalną dokumentację tutaj - https://ipynb.readthedocs.io/en/stable/
Ponadto, jeśli chcesz zaimportować tylko definicje klas i funkcji z notatnika (a nie instrukcje najwyższego poziomu), możesz użyć
ipynb.fs.defs
zamiastipynb.fs.full
. Ocenione zostanie również przypisanie do zmiennych pełnych wielkich liter.źródło
ipynb
Pakiet obsługuje również częściowe wykonanie tylko definicji. Jest to oficjalny pakiet firmy IPyhton, więc uważam, że powinna to być akceptowana odpowiedź.MyFolder/book.ipynb
Zainstaluj ipynb z wiersza poleceń
pip install import-ipynb
Zaimportuj do pliku notatnika
import import_ipynb
Teraz użyj zwykłego polecenia importu, aby zaimportować plik
import MyOtherNotebook
źródło
Możesz
import nbimporter
wtedy użyćimport notebookName
źródło
conda install -c conda-forge importnb
Powyższe komentarze są bardzo przydatne, ale są nieco trudne do wdrożenia. Poniżej kroki możesz spróbować, ja też próbowałem i zadziałało:
źródło
import callee
, po prostu nie mogłem praca.Problem polega na tym, że notatniki nie są zwykłym plikiem Pythona. Kroki, aby zaimportować
.ipynb
plik, przedstawiono poniżej: Importowanie notatnikaWklejam kod, więc jeśli potrzebujesz ... możesz po prostu szybko skopiować i wkleić. Zauważ, że na końcu mam
import primes
oświadczenie. Oczywiście będziesz musiał to zmienić. Nazwa mojego pliku toprimes.ipynb
. Od tego momentu możesz używać zawartości tego pliku tak, jak robisz to regularnie.Żałuję, że nie było prostszej metody, ale jest to prosto z dokumentacji.
Uwaga: używam jupyter, a nie 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
źródło
Nie ma żadnego problemu z używaniem Jupyter z istniejącymi lub nowymi modułami Python .py. Po uruchomieniu Jupyter po prostu uruchom Spyder (lub dowolny wybrany przez siebie edytor), aby zbudować / zmodyfikować definicje klas modułów w pliku .py, a następnie po prostu zaimportuj moduły w razie potrzeby do Jupyter.
Jedną rzeczą, która sprawia, że jest to naprawdę płynne, jest użycie rozszerzenia magicznego automatycznego przeładowania. Dokumentację dotyczącą automatycznego ładowania można znaleźć tutaj:
http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html
Oto kod, który automatycznie przeładowuje moduł po każdej modyfikacji:
# autoreload sets up auto reloading of modified .py modules import autoreload %load_ext autoreload %autoreload 2
Zauważ, że wypróbowałem kod wspomniany we wcześniejszej odpowiedzi, aby symulować ładowanie plików .ipynb jako modułów i uruchomiłem go, ale dławi się, gdy wprowadzasz zmiany w pliku .ipynb. Wygląda na to, że musisz ponownie uruchomić środowisko programistyczne Jupyter, aby ponownie załadować „moduł” .ipynb, co było dla mnie nie do przyjęcia, ponieważ wprowadzam wiele zmian w moim kodzie.
źródło
Upewnij się, że
__init__.py
w pakiecie dodano również plik, w którym znajdują się wszystkie inne pliki .ipynb.Jest to dodatek do łącza nbviewer że
minrk
isyi
podany powyżej.Miałem też podobny problem i wtedy napisałem rozwiązanie oraz link do mojego publicznego folderu na dysku Google, na którym działa przykład :)
Mój post Stackoverflow z eksperymentami krok po kroku i rozwiązaniem:
Notatnik Jupyter: Importuj plik .ipynb i uzyskaj dostęp do jego metody w innym pliku .ipynb, powodując błąd
Mam nadzieję, że pomoże to również innym. Dziękuje wszystkim!
źródło