簡體   English   中英

如何讓IPython重新加載傳遞給`ipython -i ...`的文件

[英]How do I make IPython reload a file passed to `ipython -i …`

我有一個文件/tmp/throwaway_code.py

def hello():
    print("world")

並嘗試使用IPython:

$ ipython3 -i /tmp/throwaway_code.py
In [1]: hello()
world

現在我改變了文件中的內容並想重新加載。 如何在不重新啟動IPython或模塊化代碼的情況下執行此操作?

我失敗的嘗試:

In [2]: %load_ext autoreload

In [3]: %autoreload 2

# change source file    

In [4]: hello()
world
# Expected: world2.

或者,如何以最小的努力離開並重新進入IPython會話(目前有6次擊鍵:Ctrl,D,y,Return,Up,Return)?

autoreload在這里不起作用,模塊沒有放在帶有-i選項的sys.modules

from sys import modules

modules['throwaway_code'] # KeyError

所以reload將找不到您想要重新加載的模塊。

解決它的方法是顯式import將其放在sys.modules的模塊,然后autoreload將每次都獲取更改。 因此,您應該退出IPython並使用適當的PYTHONPATH啟動它,以便您的代碼可以作為模塊導入。 您的會話應如下所示:

In [4]: ^D
Do you really want to exit ([y]/n)? y
$ PYTHONPATH=/tmp ipython3

In [1]: from throwaway_code import *

In [2]: %load_ext autoreload

In [3]: %autoreload 2

In [4]: hello()
world

In [5]: hello()
world2

在IPython3中,使用reload(mymodule),您可以在同一個包中重新加載所有模塊。 只需將此代碼粘貼到IPython3啟動文件夾中的reload.py(On Ubuntu是“〜/ .ipython / profile_default / startup /”)

import importlib

from types import ModuleType
import compileall
from filecmp import dircmp
from os.path import dirname
from glob import glob
from os.path import join


blacklist=[]
def reload(module,blacklist_appendix=[]):
    """Recursively reload modules."""
    file_paths=glob(join(dirname(module.__file__),"*.py"))
    print(file_paths)
    _reload(module,blacklist+blacklist_appendix,file_paths)



def _reload(module, blacklist=[],file_paths=[],reloadeds=[]):


    if module.__name__ in blacklist:
        print("not reloaded: "+module.__name__)
        return False

    if (module.__dict__.get("__file__")==None
        or not (module.__file__ in file_paths)
        or module.__file__ in reloadeds):
        return False

    reloadeds.append(module.__file__ )
    for attribute_name in dir(module):
        attribute = getattr(module, attribute_name)

        if type(attribute) is ModuleType:
            _reload(attribute,file_paths=file_paths,reloadeds=reloadeds)


    compileall.compile_file(module.__file__,force=True)
    print("reload start: "+module.__name__)
    importlib.reload(module)
    print("reloaded: "+module.__name__)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM