Dengan Python, setelah saya mengimpor modul X dalam sesi penerjemah menggunakan import X
, dan modul berubah di luar, saya dapat memuat ulang modul dengan reload(X)
. Perubahan tersebut kemudian tersedia di sesi penerjemah saya.
Saya bertanya-tanya apakah ini juga mungkin ketika saya mengimpor komponen Y dari modul X menggunakan from X import Y
.
Pernyataan reload Y
tersebut tidak berfungsi, karena Y bukanlah modul itu sendiri, tetapi hanya komponen (dalam hal ini kelas) di dalam modul.
Apakah mungkin untuk memuat ulang komponen individu dari sebuah modul tanpa meninggalkan sesi interpreter (atau mengimpor seluruh modul)?
EDIT:
Untuk klarifikasi, pertanyaannya adalah tentang mengimpor kelas atau fungsi Y dari modul X dan memuat ulang saat ada perubahan, bukan modul Y dari paket X.
sumber
... possible ... import a component Y from module X
" vs "question is ... importing a class or function X from a module Y
". Saya menambahkan pengeditan pada efek itu.Jawaban:
Jika Y adalah modul (dan X sebuah paket)
reload(Y)
akan baik-baik saja - jika tidak, Anda akan melihat mengapa panduan gaya Python yang baik (seperti majikan saya) mengatakan untuk tidak pernah mengimpor apa pun kecuali modul (ini adalah salah satu dari banyak alasan bagus - namun orang-orang masih tetap mengimpor fungsi dan kelas secara langsung, tidak peduli seberapa banyak saya menjelaskan bahwa itu bukan ide yang baik ;-).sumber
import this
dari prompt interaktif untuk melihat Zen of Python); dan semua alasan mengapa namespace adalah ide bagus membunyikan klakson (petunjuk visual lokal langsung bahwa nama sedang dicari, kemudahan mengejek / menyuntikkan dalam pengujian, kemampuan untuk memuat ulang, kemampuan modul untuk berubah secara fleksibel dengan mendefinisikan ulang beberapa entri, dapat diprediksi dan dikontrol perilaku serialisasi dan pemulihan data Anda [[misalnya dengan membuat acar dan membongkar]], dan seterusnya, dan seterusnya - komentar SO hampir tidak cukup untuk melakukan keadilan terhadap argumen yang panjang dan kaya ini !!! -)importlib
paket.importlib.reload(Y)
docs.python.org/3.4/library/… lihat juga stackoverflow.com/questions/961162/…Menjawab
Dari pengujian saya, jawaban yang ditandai, yang menyarankan sederhana
reload(X)
, tidak berhasil.Dari apa yang bisa saya katakan, jawaban yang benar adalah:
from importlib import reload # python 2.7 does not require this import X reload( X ) from X import Y
Uji
Tes saya adalah sebagai berikut (Python 2.6.5 + bpython 0.9.5.2)
X.py:
def Y(): print "Test 1"
bpython:
>>> from X import Y >>> print Y() Test 1 >>> # Edit X.py to say "Test 2" >>> print Y() Test 1 >>> reload( X ) # doesn't work because X not imported yet Traceback (most recent call last): File "<input>", line 1, in <module> NameError: name 'X' is not defined >>> import X >>> print Y() Test 1 >>> print X.Y() Test 1 >>> reload( X ) # No effect on previous "from" statements >>> print Y() Test 1 >>> print X.Y() # first one that indicates refresh Test 2 >>> from X import Y >>> print Y() Test 2 >>> # Finally get what we were after
sumber
Foo
yang memiliki__init__.py
yang mengambil submodul ... Saya akan memposting jawaban sebagai contoh balasan.from modulename import func import importlib, sys importlib.reload(sys.modules['modulename']) from modulename import func
sumber
Pertama, Anda tidak boleh menggunakan isi ulang sama sekali, jika Anda bisa menghindarinya. Tapi mari kita asumsikan Anda memiliki alasan Anda (yaitu debugging di dalam IDLE).
Memuat ulang pustaka tidak akan mengembalikan nama ke ruang nama modul. Untuk melakukan ini, cukup tetapkan kembali variabel:
f = open('zoo.py', 'w') f.write("snakes = ['viper','anaconda']\n") f.close() from zoo import snakes print snakes f = open('zoo.py', 'w') f.write("snakes = ['black-adder','boa constrictor']\n") f.close() import zoo reload(zoo) snakes = zoo.snakes # the variable 'snakes' is now reloaded print snakes
Anda dapat melakukan ini dengan beberapa cara lain. Anda dapat mengotomatiskan proses dengan mencari melalui namespace lokal, dan menetapkan ulang apa pun yang berasal dari modul tersebut, tetapi saya pikir kami cukup jahat.
sumber
Jika Anda ingin melakukan ini:
from mymodule import myobject
Lakukan ini sebagai gantinya:
import mymodule myobject=mymodule.myobject
Anda sekarang dapat menggunakan myobject dengan cara yang sama seperti yang Anda rencanakan (tanpa referensi mymodule tidak terbaca yang melelahkan di mana-mana).
Jika Anda bekerja secara interaktif dan ingin memuat ulang myobject dari mymodule, Anda sekarang dapat menggunakan:
sumber
dengan asumsi Anda menggunakan
from X import Y
, Anda memiliki dua opsi:reload(sys.modules['X']) reload(sys.modules[__name__]) # or explicitly name your module
atau
Y=reload(sys.modules['X']).Y
beberapa pertimbangan:
A. jika cakupan impor tidak selebar modul (misalnya, impor dalam fungsi) - Anda harus menggunakan versi kedua.
B. jika Y diimpor ke X dari modul lain (Z) - Anda harus memuat ulang Z, lalu memuat ulang X dan kemudian memuat ulang modul Anda, bahkan memuat ulang semua modul Anda (e, g: using
[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
) mungkin memuat ulang X sebelum memuat ulang Z - dan kemudian tidak menyegarkan nilai Y.sumber
reload()
modulX
,reload()
modul mengimporY
dariX
.Perhatikan bahwa memuat ulang tidak akan mengubah objek yang sudah dibuat yang terikat di ruang nama lain (meskipun Anda mengikuti panduan gaya dari Alex).
sumber
Jika Anda bekerja di lingkungan jupyter, dan Anda sudah
from module import function
dapat menggunakan fungsi ajaib,autoreload
dengan%load_ext autoreload %autoreload from module import function
Pengenalan
autoreload
di IPython diberikan di sini .sumber
Hanya untuk menindaklanjuti AlexMartelli ini dan Catskul ini jawaban, ada beberapa kasus benar-benar sederhana tapi jahat yang muncul untuk mencampuradukkan
reload
, setidaknya dalam Python 2.Misalkan saya memiliki pohon sumber berikut:
dengan konten berikut:
init.py:
from bar import Bar, Quux
bar.py:
print "Loading bar" class Bar(object): @property def x(self): return 42 class Quux(Bar): object_count = 0 def __init__(self): self.count = self.object_count self.__class__.object_count += 1 @property def x(self): return super(Quux,self).x + 1 def __repr__(self): return 'Quux[%d, x=%d]' % (self.count, self.x)
Ini berfungsi dengan baik tanpa menggunakan
reload
:>>> from foo import Quux Loading bar >>> Quux() Quux[0, x=43] >>> Quux() Quux[1, x=43] >>> Quux() Quux[2, x=43]
Tetapi coba muat ulang dan itu tidak berpengaruh atau merusak hal-hal:
>>> import foo Loading bar >>> from foo import Quux >>> Quux() Quux[0, x=43] >>> Quux() Quux[1, x=43] >>> reload(foo) <module 'foo' from 'foo\__init__.pyc'> >>> Quux() Quux[2, x=43] >>> from foo import Quux >>> Quux() Quux[3, x=43] >>> reload(foo.bar) Loading bar <module 'foo.bar' from 'foo\bar.pyc'> >>> Quux() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "foo\bar.py", line 17, in __repr__ return 'Quux[%d, x=%d]' % (self.count, self.x) File "foo\bar.py", line 15, in x return super(Quux,self).x + 1 TypeError: super(type, obj): obj must be an instance or subtype of type >>> Quux().count 5 >>> Quux().count 6 >>> Quux = foo.bar.Quux >>> Quux() Quux[0, x=43] >>> foo.Quux() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "foo\bar.py", line 17, in __repr__ return 'Quux[%d, x=%d]' % (self.count, self.x) File "foo\bar.py", line 15, in x return super(Quux,self).x + 1 TypeError: super(type, obj): obj must be an instance or subtype of type >>> foo.Quux().count 8
Satu-satunya cara saya bisa memastikan
bar
submodul dimuat ulang adalah denganreload(foo.bar)
; satu-satunya cara saya mengaksesQuux
kelas yang dimuat ulang adalah dengan menjangkau dan mengambilnya dari sub modul yang dimuat ulang; tetapifoo
modul itu sendiri tetap memegangQuux
objek kelas asli , mungkin karena ia menggunakanfrom bar import Bar, Quux
(daripadaimport bar
diikuti olehQuux = bar.Quux
); Selain itu,Quux
kelas menjadi tidak selaras dengan dirinya sendiri, yang sungguh aneh.sumber