Nhập lại một mô-đun trong python trong khi tương tác


383

Tôi biết nó có thể được thực hiện, nhưng tôi không bao giờ nhớ làm thế nào.

Làm thế nào bạn có thể nhập lại một mô-đun trong python? Kịch bản như sau: Tôi nhập một mô-đun tương tác và sửa lại nó, nhưng sau đó tôi gặp phải một lỗi. Tôi sửa lỗi trong tệp .py và sau đó tôi muốn nhập lại mô-đun đã sửa mà không thoát python. Tôi làm nó như thế nào ?



Câu trả lời:


369

Điều này sẽ làm việc:

reload(my.module)

Từ các tài liệu Python

Tải lại một mô-đun đã nhập trước đó. Đối số phải là một đối tượng mô-đun, vì vậy nó phải được nhập thành công trước đó. Điều này hữu ích nếu bạn đã chỉnh sửa tệp nguồn mô-đun bằng trình chỉnh sửa bên ngoài và muốn dùng thử phiên bản mới mà không cần rời khỏi trình thông dịch Python.

Nếu chạy Python 3.4 trở lên, hãy làm import importlib, sau đó làm importlib.reload(nameOfModule).

Đừng quên những cảnh báo khi sử dụng phương pháp này:

  • Khi một mô-đun được tải lại, từ điển của nó (chứa các biến toàn cục của mô-đun) được giữ lại. Định nghĩa lại tên sẽ ghi đè các định nghĩa cũ, do đó, đây thường không phải là vấn đề, nhưng nếu phiên bản mới của mô-đun không xác định tên được xác định bởi phiên bản cũ, định nghĩa cũ sẽ không bị xóa.

  • Nếu một mô-đun nhập các đối tượng từ một mô-đun khác bằng cách sử dụng from ... import ..., việc gọi reload()cho mô-đun khác không xác định lại các đối tượng được nhập từ mô-đun này - một cách khác là thực hiện lại fromcâu lệnh, thay vào đó là sử dụng importvà sử dụng tên đủ điều kiện ( module.*name*).

  • Nếu một mô-đun khởi tạo các thể hiện của một lớp, việc tải lại mô-đun xác định lớp đó không ảnh hưởng đến các định nghĩa phương thức của các thể hiện - chúng tiếp tục sử dụng định nghĩa lớp cũ. Điều này cũng đúng với các lớp dẫn xuất.


26
nếu tôi tải các mô-đun của tôi bằng cách sử dụng from filename import *. Làm thế nào để tải lại?
Peter Zhu

@PeterZhu cho trường hợp "từ mod nhập fcn", đối tượng mô-đun không được thêm vào không gian tên. Vì vậy, bạn cần phải nhập mô-đun một cách rõ ràng, để sau này bạn có thể tải lại nó. import foo; from foo import bar; reload(foo)
Ted

Tôi đã thử tải lại, cũng như ma thuật tự động tải và tôi thấy thay đổi mã của mình được phản ánh trong ngăn xếp của thông báo lỗi, nhưng bản thân lỗi vẫn xuất hiện ngoài mã cũ (ví dụ: dòng lỗi là chính xác như trước đây, mà tôi đã thay đổi thành một nhận xét và một nhận xét rõ ràng không thể gây ra lỗi). Mô-đun của tôi được tải dưới dạng tiện ích mở rộng Jupyter, có ai có thể biết nếu điều này yêu cầu một công việc khác không? Cảm ơn!
yifanwu

1
Nếu bạn đã nhập chức năng của mình như sau "nhập mod dưới tên", thì bạn cần thực hiện như sau: 'nhập importlib importlib.reload (name)'
Noe

Phương pháp này có thể không ghi đè các tham chiếu của các mô-đun khác vào mô-đun được tải lại. Xem stackoverflow.com/a/61617169/2642356 để biết giải pháp cho vấn đề đó.
EZLearner

287

Trong python 3, reloadkhông còn là hàm dựng sẵn.

Nếu bạn đang sử dụng python 3.4+, bạn nên sử dụng reloadtừ importlibthư viện:

import importlib
importlib.reload(some_module)

Nếu bạn đang sử dụng python 3.2 hoặc 3.3, bạn nên:

import imp  
imp.reload(module)  

thay thế. Xem http://docs.python.org/3.0/l Library / view.html # view.reload

Nếu bạn đang sử dụng ipython, chắc chắn xem xét sử dụng autoreloadtiện ích mở rộng:

%load_ext autoreload
%autoreload 2

Mặc dù nhiều mã Python được viết bằng Python 2, Python 3 đang trở thành một tùy chọn khả thi hơn mỗi ngày. Cảm ơn vì tiền hỗ trợ!
Aaron Johnson

40
imp.reloadkhông dùng nữa vì Python 3.4, sử dụng importlib.reloadhàm thay thế.
jfs

1
@ Cảm ơn! Tôi đã sử dụng% autoreload, thật tuyệt vời, các đối tượng đã được tạo của tôi tự động thực hiện đúng các phương thức lớp mà không phải tạo lại chúng
jeanmi

4
Tôi hơi muộn, nhưng tôi nghĩ rằng điều này không làm việc nếu những gì bạn cần phải tải lại là một hàm hoặc lớp từ bên trong các mô-đun: nếu Statment khẩu của tôi là from mymodule import myfunc, sau đó importlib.reload(myfunc), importlib.reload(mymodule.myfunc), importlib.reload(mymodule)tất cả cho một NameError.
Puff

@Puff xem câu trả lời của tôi dưới đây để biết cách nhập lại một chức năng
jss367


6

Nếu bạn muốn nhập một chức năng hoặc lớp cụ thể từ một mô-đun, bạn có thể làm điều này:

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

0

Mặc dù các câu trả lời được cung cấp có tác dụng với một mô-đun cụ thể, nhưng chúng sẽ không tải lại các mô hình con, như đã lưu ý trong Câu trả lời này :

Nếu một mô-đun nhập các đối tượng từ một mô-đun khác bằng cách sử dụng from ... import ..., việc gọi reload()cho mô-đun khác không xác định lại các đối tượng được nhập từ mô-đun này - một cách khác là thực hiện lại câu lệnh from, thay vào đó là sử dụng importtên và đủ điều kiện ( module.*name*).

Tuy nhiên, nếu sử dụng __all__biến để xác định API công khai, có thể tự động tải lại tất cả các mô-đun có sẵn công khai:

# 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)

Mặc dù vậy, các lưu ý trong câu trả lời trước vẫn còn hiệu lực. Đáng chú ý, việc sửa đổi một mô hình con không phải là một phần của API công khai như được mô tả bởi __all__biến sẽ không bị ảnh hưởng bởi tải lại khi sử dụng chức năng này. Tương tự, việc loại bỏ một phần tử của mô hình con sẽ không được phản ánh bằng tải lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.