2010-03-28 23 views
21

Tôi đang gỡ lỗi từ bảng điều khiển python và muốn tải lại mô-đun mỗi khi tôi thực hiện thay đổi, vì vậy tôi không phải thoát khỏi bảng điều khiển và nhập lại. Tôi đang thực hiện:Cách thích hợp để tải lại mô-đun python từ giao diện điều khiển

>>> from project.model.user import * 
>>> reload(user) 

nhưng tôi nhận được:

>>>NameError: name 'user' is not defined 

cách thích hợp để tải lại toàn bộ lớp người sử dụng là gì? Có cách nào tốt hơn để làm điều này, có lẽ tự động cập nhật trong khi gỡ lỗi?

Cảm ơn.

Trả lời

29

Như hỏi, tốt nhất bạn có thể làm là

>>> from project.models.user import * 
>>> import project # get module reference for reload 
>>> reload(project.models.user) # reload step 1 
>>> from project.models.user import * # reload step 2 

nó sẽ được tốt hơn và sạch hơn nếu bạn sử dụng các module sử dụng trực tiếp, chứ không phải là làm import * (đó là gần như không bao giờ đúng cách để làm điều đó) . Sau đó, nó sẽ chỉ là

>>> from project.models import user 
>>> reload(user) 

Điều này sẽ làm những gì bạn muốn. Nhưng, nó không phải là rất tốt đẹp. Nếu bạn thực sự cần tải lại các mô-đun một cách thường xuyên, tôi phải hỏi: tại sao?

Sự nghi ngờ của tôi (được hỗ trợ bởi trải nghiệm trước đó với những người đặt câu hỏi tương tự) là bạn đang thử nghiệm mô-đun của mình. Có rất nhiều cách để kiểm tra một mô-đun, và thực hiện nó bằng tay trong trình thông dịch tương tác là một trong những cách tồi tệ nhất. Lưu một trong các phiên của bạn vào một tệp và sử dụng doctest để khắc phục nhanh chóng. Ngoài ra, viết nó ra như một chương trình và sử dụng python -i. Tuy nhiên, giải pháp thực sự tuyệt vời nhất là sử dụng mô-đun unittest.

Nếu không phải như vậy, hy vọng nó tốt hơn, không tệ hơn. Có thực sự không sử dụng tốt của reload (trên thực tế, nó được loại bỏ trong 3.x). Nó không hoạt động hiệu quả - bạn có thể tải lại một mô-đun nhưng để lại các phần còn lại từ các phiên bản trước. Nó thậm chí không hoạt động trên tất cả các loại module-- mô-đun mở rộng sẽ không tải lại đúng cách, hoặc đôi khi thậm chí phá vỡ khủng khiếp, khi được tải lại.

Ngữ cảnh sử dụng nó trong trình thông dịch tương tác không để lại nhiều lựa chọn như những gì bạn đang làm và giải pháp thực sự tốt nhất sẽ là gì.Bên ngoài nó, đôi khi mọi người sử dụng reload() để triển khai plugin, v.v. Điều này rất nguy hiểm ở mức tốt nhất và có thể được thực hiện khác nhau bằng cách sử dụng exec (ah lãnh thổ tà ác mà chúng tôi tìm thấy) hoặc một quy trình tách biệt.

+0

+1: Thực sự không sử dụng tốt việc tải lại. –

+0

Tôi đang làm gì để tìm câu hỏi này, tôi đang sử dụng bảng điều khiển để khám phá cấu trúc dữ liệu được nhập từ JSON. Tôi muốn sử dụng "tải lại" để giữ một số chức năng trong trình soạn thảo văn bản của tôi đi qua cấu trúc theo các cách khác nhau, chỉnh sửa chúng, sau đó chạy lại chúng mà không phải thoát khỏi bàn điều khiển. Tuy nhiên, nếu Python không thể hỗ trợ điều đó một cách rõ ràng, vì các lý do thực hiện như không có khả năng loại bỏ "các thức ăn thừa", tôi đoán tôi phải sai khi muốn làm điều đó ;-p +1 cho câu trả lời cho phép tôi làm điều đó, Tuy nhiên. –

+0

+1 cho tôi thấy rằng tôi nên, thực sự thực sự, là viết bài kiểm tra thay vì làm những việc trong thông dịch viên bằng tay, ngay cả đối với tinh chỉnh. Điều này cũng sẽ hữu ích cho thử nghiệm không hồi quy trong tương lai. –

4

Đáng tiếc là bạn đã có để sử dụng:

>>> from project.model import user 
>>> reload(user) 

Tôi không biết ra khỏi đỉnh đầu của tôi về một cái gì đó mà sẽ tự động tải lại các module tại dấu nhắc tương tác ... Nhưng tôi không thấy lý do nào đó người ta không nên tồn tại (trong thực tế, nó sẽ không quá khó để thực hiện, hoặc là ...)

Bây giờ, bạn có thể làm điều gì đó như thế này:

from types import ModuleType 
import sys 
_reload_builtin = reload 
def reload(thing): 
    if isinstance(thing, ModuleType): 
     _reload_builtin(thing) 
    elif hasattr(thing, '__module__') and thing.__module__: 
     module = sys.modules[thing.__module__] 
     _reload_builtin(module) 
    else: 
     raise TypeError, "reload() argument must be a module or have an __module__" 
4

Bạn không thể sử dụng tải lại() một cách hiệu quả.

Python không cung cấp hỗ trợ hiệu quả cho việc tải lại hoặc dỡ các mô-đun đã nhập trước đây; tham chiếu mô-đun làm cho việc tải lại mô-đun trở nên không thực tế vì các tham chiếu có thể tồn tại ở nhiều nơi trong chương trình của bạn.

Python 3 đã xóa hoàn toàn tính năng tải lại().

+1

Đó không phải là tham chiếu mô-đun thực hiện: tải lại() thực sự làm thay đổi đối tượng mô-đun. Đó là các tham chiếu đến các hàm và các lớp bên trong mô-đun phá vỡ mọi thứ (đặc biệt, các tham chiếu được tạo ra từ việc nhập khẩu foo *). –

+0

Có, tôi đồng ý và bạn có thể có các mô-đun chương trình khác đã nhập mô-đun mà bạn muốn bỏ tải(). – systempuntoout

1

IPython có thể tải lại các module trước khi thực hiện tất cả các dòng sản phẩm mới:

%load_ext autoreload 
%autoreload 2 

đâu %autoreload 2 load lại "tất cả các module (trừ những loại trừ bởi% aimport) mỗi lần trước khi thực hiện mã Python gõ"

Xem các tài liệu:

1

Đối python3, tải lại đã được chuyển đến imp module. bạn có thể sử dụng imp.reload(). Bạn có thể tham khảo this post.

>>> import imp 
>>> import project # get module reference for reload 
>>> imp.reload(project.models.user) # reload step 1 
>>> from project.models.user import * # reload step 2 
Các vấn đề liên quan