2015-04-22 31 views
0

我有一個函數存儲在一個.py文件中,稱之爲my_methods。ipython筆記本中的python訪問函數

def print_text(myText): 
    print myText 

我使用ipython筆記本來做我的開發(本地服務器),並且my_methods文件經常變化。

我想使用runipy通過引用my_methods中的函數的shell腳本來運行其他ipython筆記本。例如,正在從一個shell腳本啓動一個IPython的筆記本應該是這樣的:

import my_methods as mm 

mm.print_text("print me") 

如何設置這個向上,以便在進口my_methods線可以從IPython的筆記本電腦(.ipynb)獲得print_text功能,而不是.py版本?目前,我必須將my_methods筆記本作爲.py文件下載,這會導致版本控制問題(my_methods的.ipynb版本與下載的.py版本不同)

感謝您的幫助!

編輯

所以通過被顯示爲答案博客文章看完之後我做了少許修改的find_notebook功能。如果沒有提供ipython筆記本的路徑,我只是通過sys.path讀取的,而不是當前目錄。我也沒有像以前那樣在linux機器上運行,所以它使我更容易將所有添加的python文件保存在一個單獨的目錄中,該目錄包含在我的路徑變量中。我保存在一個名爲iPyLoader模塊下面的代碼,然後先導入它在我的其他模塊:

import io, os, sys, types 
from IPython import get_ipython 
from IPython.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 = sys.path #EDITED HERE RATHER THAN CURRENT DIRECTORY 
    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 IPython 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) 

     print ("importing IPython 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 IPython 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 iPyLoader 
import testnotebook as printer #this is an .ipynb file 
printer.myprinter("test") 

,輸出將是:

importing IPython notebook from C:\Python27\lib\testnotebook.ipynb 
test 
+1

我想你正在尋找[this](http://stackoverflow.com/q/19640280/2870069) – Jakob

+0

對政府工作來說足夠了,謝謝! – flyingmeatball

回答

0

一個很好的近似值是here

簡單的方法不存在,因爲ipython筆記本不是普通的純文本。

+0

是應該這樣做的,謝謝 – flyingmeatball