IPython'a alt modüllerin yeniden yüklenmesi


363

Şu anda alt modülleri içeren ve numpy / scipy kullanan bir python projesi üzerinde çalışıyorum. Ipython etkileşimli konsol olarak kullanılır. Ne yazık ki şu anda kullandığım iş akışından çok memnun değilim, bazı tavsiyeleri takdir ediyorum.

IPython'da çerçeve basit bir importkomutla yüklenir . Bununla birlikte, genellikle çerçevenin alt modüllerinden birinde kodu değiştirmek gerekir. Bu noktada bir model zaten yüklü ve ben onunla etkileşim için IPython kullanıyorum.

Şimdi, çerçeve birbirine bağlı birçok modül içerir, yani çerçeve ilk yüklendiğinde ana modül alt modülleri içe aktarır ve yapılandırır. Koddaki değişiklikler sadece modül kullanılarak yeniden yüklenirse yürütülür reload(main_mod.sub_mod). Değiştirilen tüm modülleri tam yolu kullanarak ayrı ayrı yeniden yüklemem gerektiğinden bu hantal. reload(main_module)Tüm alt modülleri de yeniden yüklemeniz çok uygun olurdu, ancak numpy / scipy'yi yeniden yüklemeden ..


Daha fazla ayrıntıya girmeyi düşünür müsünüz However, it is often necessary to change code in one of the submodules of the framework.Peki neden necessary to change code? Teşekkürler
yemek

16
@eat: Çerçeve sürekli olarak geliştirilmektedir, bu nedenle kod tabanında sürekli değişiklikler vardır.
Alain

Yanıtlar:


531

IPython bazı otomatik yeniden yükleme sihirleriyle birlikte gelir :

%load_ext autoreload
%autoreload 2

Yeni bir hat çalıştırmadan önce her değiştirilen modülü yeniden yükleyecektir. Bunun çalışma şekli biraz farklı dreload. Bazı uyarılar geçerlidir, %autoreload?neyin yanlış gidebileceğini görmek için yazın .


Bu ayarları her zaman etkinleştirmek istiyorsanız, IPython yapılandırma dosyanızı ~/.ipython/profile_default/ipython_config.py[1] değiştirin ve ekleyin :

c.InteractiveShellApp.extensions = ['autoreload']     
c.InteractiveShellApp.exec_lines = ['%autoreload 2']

Aşağıdaki yorum ile @Kos'a teşekkür ederiz.

[1] Dosyanız ~/.ipython/profile_default/ipython_config.pyyoksa, ipython profile createönce aramanız gerekir . Veya dosya adresinde bulunabilir $IPYTHONDIR.


63
Ben c.InteractiveShellApp.extensions = ['autoreload']ve c.InteractiveShellApp.exec_lines = ['%autoreload 2']benim, ~/.ipython/profile_default/ipython_config.py.
Kos

4
Bu bir performans isabeti olabilir, bu yüzden dikkatli kullanın.
asmeurer

3
Yeniden yükleme yalnızca Ipython kabuğunda Enter tuşuna bastığınızda yapılır ve genellikle farkedilmez.
pv.

3
Bu, paketleri hata ayıklarken oldukça iyi çalışır, bu nedenle dreload'un amacı nedir, dreload çok invaziv görünüyor ve matplotlib gibi bazı paketler yüklendiğinde hata yazdırıyor.
dashesy

3
@Kos yöntemini kullanırsanız, c'nin tanımlandığından emin olun: c = get_config ()
Tickon

27

IPython 0.12'de (ve muhtemelen daha önce), bunu kullanabilirsiniz:

%load_ext autoreload
%autoreload 2

Bu aslında pv'nin cevabı ile aynıdır . hariç, uzantı yeniden adlandırılmış ve şimdi kullanılarak yüklenmiştir %load_ext.



18

IPython, dreload()tüm alt modülleri tekrar tekrar yüklemeyi önerir . Şahsen, %run()sihirli komutu kullanmayı tercih ediyorum (yorumlarda John Salvatier'in işaret ettiği gibi derin bir yeniden yükleme yapmasa da).


11
Bence (ne yazık ki)% script.py çalıştırmak ithal paketleri değil sadece aradığınız komut dosyasını yeniden yükler düşünüyorum. Oluşturduğunuz bir paketin hatalarını ayıklamaya çalışıyorsanız, bu bir acı olabilir.
John Salvatier

2
NB. dreloadson IPython'da (örn. IPython 6.0) derinden yükleme ile değiştirildi .
dan mackinlay

8

Adlı modül importlib, içe aktarılan iç öğelere erişime izin verir. Özellikle, fonksiyon sağlar importlib.reload():

import importlib
importlib.reload(my_module)

Zıttıdır olarak %autoreload, importlib.reload()ayrıca modül ayarlanan genel değişkenleri sıfırlanır. Çoğu durumda, istediğiniz şeydir.

importlibyalnızca Python 3.1'den beri kullanılabilir. Eski sürüm için modül kullanmanız gerekir imp.


benim için çalışan sadece çözüm
gustavz

5

http://shawnleezx.github.io/blog/2015/08/03/some-notes-on-ipython-startup-script/

Bu sihirli işlevi tekrar tekrar yazmaktan kaçınmak için, ipython başlangıç ​​komut dosyasına (.ipython / profile_default / startup altında .py son ekiyle adlandırın. Bu klasör altındaki tüm python komut dosyaları sözcük sırasına göre yüklenecektir). aşağıdaki gibi görünüyor:

from IPython import get_ipython
ipython = get_ipython()

ipython.magic("pylab")
ipython.magic("load_ext autoreload")
ipython.magic("autoreload 2")

Komut dosyanızı örneğin %run script.pyIPython REPL
Patrick Sanan

3

Buna ne dersin:

import inspect

# needs to be primed with an empty set for loaded
def recursively_reload_all_submodules(module, loaded=None):
    for name in dir(module):
        member = getattr(module, name)
        if inspect.ismodule(member) and member not in loaded:
            recursively_reload_all_submodules(member, loaded)
    loaded.add(module)
    reload(module)

import mymodule
recursively_reload_all_submodules(mymodule, set())

Bu, verdiğiniz tüm modül ve alt modül ağacını etkili bir şekilde yeniden yüklemelidir. Ayrıca bu işlevi .ipythonrc (bence) içine koyabilirsiniz, böylece yorumlayıcıyı her başlattığınızda yüklenir.


Bu iyi görünüyor, ancak bu modüller kullanılarak veya ithal edilen modüllerin üyelerini kapsayan olmadığını olabilir from ... import ...veya import ... as. En azından bu, terminalde etkileşimli olarak çalışırken bana sık sık sıkıntı veriyor. Önceden tanımlanmış bir durumda çalışmaya başlamak için gerekli içe aktarma ve kurulumları yapan IPython'da depolanmış makroları kullanmaya devam ettim.
Bernhard

Aslında kapsar from ... import ...ve import ... asaldığınız şey bir modül olduğu sürece. Kapsadığı tek şey, bir paketin __init__.pydosyasından yüklenmemiş modüllerdir . Paketler için, modülün __path__özelliğinin bir dizin olup olmadığını kontrol edebilirsiniz . Öyleyse, onu gezdirin ve bulabileceğiniz tüm modülleri tekrar tekrar içe aktarın. Bu bölümü yazmadım çünkü yazar paketler için bir çözüm istemedi.
YH Wong

Gerçekten de bu iyi görünüyor. Bazı dayalı yani işlevselliği inşa edileceğini beklenebilir aynı I, bu olasılığı hakkında düşünce bu . Ancak bunun nasıl kullanılacağı açık değildi. Orijinal soruyu göndermeden önce olması gereken bazı kazmalardan sonra, bu uzantıyı buldum .
Alain

Ayrıca pkgutil, paket alt modülleri üst modüle almasa bile, tüm alt modülleri bir pakette almak için kullanabilirsiniz . stackoverflow.com/a/1707786/1243926
osa

Ayrıca şunları da yapmalısınız: modül içindesys.modules:
aoeu256

2

Başka seçenek:

$ cat << EOF > ~/.ipython/profile_default/startup/50-autoreload.ipy
%load_ext autoreload
%autoreload 2
EOF

Ubuntu 14.04'te ipython ve ipython3 v5.1.0'da doğrulandı.


1

Yeniden yükleme için standart pratiğim, ilk açılışın ardından her iki yöntemi birleştirmektir IPython:

from IPython.lib.deepreload import reload
%load_ext autoreload
%autoreload 2

Bunu yapmadan önce modüllerin yüklenmesi, bir el kitabı ile bile yeniden yüklenmemelerine neden olacaktır reload(module_name). Hala, henüz bakmadığım yeniden yüklenmeyen sınıf yöntemleri ile açıklanamayan problemler alıyorum.


1

Yukarıda belirtilenlerin autoreloadyalnızca değiştirilen dosyayı manuel olarak kaydederseniz (örn. Ctrl + s veya cmd + s kullanarak) IntelliJ'de çalıştığını unutmayın . Otomatik kaydetme ile çalışmıyor gibi görünüyor.


Bunun PyCharm için de geçerli olduğunu onaylıyorum.
tsando

0

Anaconda'daki Jupyter Notebook'larda şunları yapıyor:

%load_ext autoreload
%autoreload 2

mesajı üretti:

Otomatik yeniden yükleme uzantısı zaten yüklenmiş. Yeniden yüklemek için şunu kullanın: %reload_ext autoreload

Yapılması tercih edilir gibi görünüyor:

%reload_ext autoreload
%autoreload 2

Versiyon bilgisi:

Dizüstü bilgisayar sunucusunun sürümü 5.0.0 ve üzerinde çalışıyor: Python 3.6.2 | Anaconda, Inc. | (varsayılan, 20 Eyl 2017, 13:35:58) [MSC v.1900 32 bit (Intel)]


0

Herhangi bir alt nesne yeniden yüklenmeyecek, bunun için IPython'un derin yeniden yüklemesini kullanmanız gerektiğine inanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.