İnteraktifken bir modülü python'a yeniden aktarın


383

Bunun yapılabileceğini biliyorum, ama nasıl olduğunu asla hatırlamıyorum.

Python'da bir modülü nasıl yeniden içe aktarabilirsiniz? Senaryo aşağıdaki gibidir: Bir modülü etkileşimli olarak içe aktarıyorum ve onunla tamir ediyorum, ama sonra bir hatayla karşılaşıyorum. .Py dosyasındaki hatayı düzelttim ve sonra sabit modülü python'dan çıkmadan yeniden içe aktarmak istiyorum. Nasıl yapabilirim ?



Yanıtlar:


369

Bu çalışmalı:

reload(my.module)

Gönderen Python docs

Önceden içe aktarılmış bir modülü yeniden yükleyin. Bağımsız değişken bir modül nesnesi olmalı, bu nedenle daha önce başarıyla içe aktarılmış olmalıdır. Harici bir düzenleyici kullanarak modül kaynak dosyasını düzenlediyseniz ve Python yorumlayıcısından çıkmadan yeni sürümü denemek istiyorsanız bu yararlıdır.

Python 3.4 ve üstünü çalıştırıyorsanız import importlib, yapın ve ardındanimportlib.reload(nameOfModule) .

Bu yöntemi kullanmanın uyarılarını unutmayın:

  • Bir modül yeniden yüklendiğinde, sözlüğü (modülün global değişkenlerini içeren) korunur. Adların yeniden tanımlanması eski tanımları geçersiz kılar, bu nedenle bu genellikle bir sorun değildir, ancak bir modülün yeni sürümü eski sürüm tarafından tanımlanan bir ad tanımlamazsa, eski tanım kaldırılmaz.

  • Bir modül kullanarak başka bir modülden nesne alırsa , diğer modülü from ... import ...çağırmak reload()ondan içe aktarılan nesneleri yeniden tanımlamaz - bunun bir yolu fromifadeyi yeniden yürütmektir , diğeri bunun yerine importve nitelikli adlar ( module.*name*) kullanmaktır.

  • Bir modül bir sınıfın örneklerini başlatırsa, sınıfı tanımlayan modülü yeniden yüklemek, örneklerin yöntem tanımlarını etkilemez - eski sınıf tanımını kullanmaya devam ederler. Aynı şey türetilmiş sınıflar için de geçerlidir.


26
kullanarak modüllerimi yüklersem from filename import *. Nasıl yeniden yüklenir?
Peter Zhu

@PeterZhu "mod import fcn" durumunda, modül nesnesi ad alanına eklenmez. Bu nedenle, modülü daha sonra içe aktarmanız gerekir, böylece daha sonra yeniden yükleyebilirsiniz. import foo; from foo import bar; reload(foo)
Ted

Yeniden yükleme yanı sıra autoreload büyü denedim ve kod değişikliği hata iletisinin yığın yansıtıldığını görüyorum, ancak hata hala eski kodu kapalı gibi görünüyor (örneğin, hata satırı tamamen aynı daha önce olduğu gibi, bir yorum olarak değiştirdim ve bir yorum açıkça hatalara neden olamaz). Modülüm bir Jupyter Uzantısı olarak yüklendi, bunun farklı bir çalışma gerektirip gerektirmediğini bilen var mı? Teşekkürler!
yifanwu

1
İşlevinizi "ad olarak mod alma" olarak içe aktardıysanız, aşağıdaki işlemleri yapmanız gerekir: 'import importlib importlib.reload (name)'
Noe

Bu yöntem, diğer modüllerin yeniden yüklenen modüle olan referanslarını geçersiz kılamayabilir. Bunun çözümü için stackoverflow.com/a/61617169/2642356 adresine bakın .
EZLearner

287

Python 3'te, reload artık yerleşik bir işlev değildir.

Python 3.4+ kullanıyorsanız reload, importlibbunun yerine kütüphaneden kullanmalısınız:

import importlib
importlib.reload(some_module)

Python 3.2 veya 3.3 kullanıyorsanız:

import imp  
imp.reload(module)  

yerine. Bkz. Http://docs.python.org/3.0/library/imp.html#imp.reload

Kullanıyorsanız ipython, kesinlikle autoreloaduzantıyı kullanmayı düşünün :

%load_ext autoreload
%autoreload 2

Python 2'de çok fazla Python kodu yazılmasına rağmen, Python 3 her gün daha uygun bir seçenek haline geliyor. Bahşiş için teşekkürler!
Aaron Johnson

40
imp.reloadPython 3.4'ten beri kullanımdan kaldırıldı, bunun yerine importlib.reloadişlevi kullanın.
jfs

1
@ Ve teşekkürler! % Autoreload kullandım, bu harika, zaten oluşturulan nesneleri otomatik olarak sınıf yöntemleri onları yeniden oluşturmak zorunda düzeltilmiş uygulaması var
jeanmi

4
Ben biraz geciktim ama ne yeniden yükleme için gereken modülü içinde bir işlev veya sınıf ise bu çalışmayı değil düşünüyorum: İçe aktarma statment olsaydı from mymodule import myfunc, o zaman importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)bütün bir NameError verir.
Puff

@Puff bir işlevi nasıl tekrar içe aktaracağımı öğrenmek için aşağıdaki cevabımı görüyorum
jss367


6

Bir modülden belirli bir işlevi veya sınıfı içe aktarmak istiyorsanız, bunu yapabilirsiniz:

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

0

Verilen cevaplar belirli bir modül için çalışsa da, Bu cevapta belirtildiği gibi alt modülleri yeniden yüklemezler :

Bir modül kullanarak başka bir modülden nesneleri içe aktarırsa , diğer modülü from ... import ...çağırmak reload()ondan içe aktarılan nesneleri yeniden tanımlamaz - bunun bir yolu from ifadesini yeniden çalıştırmaktır, diğeri bunun yerine importve nitelikli adlar ( module.*name*) kullanmaktır.

Ancak, __all__genel API'yı tanımlamak için değişken kullanılıyorsa, herkese açık tüm modülleri otomatik olarak yeniden yüklemek mümkündür:

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

Önceki cevapta belirtilen uyarılar yine de geçerlidir. Özellikle, __all__değişken tarafından açıklandığı gibi genel API'nın bir parçası olmayan bir alt modülün değiştirilmesi, bu işlevi kullanan bir yeniden yüklemeden etkilenmez. Benzer şekilde, bir alt modülün bir elemanının çıkarılması yeniden yükleme ile yansıtılmaz.

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.