15

Các Django docs nói điều này về đề tài này:Tại sao xử lý tín hiệu của Django sử dụng tham chiếu yếu cho các cuộc gọi lại theo mặc định?

Cũng lưu ý rằng các cửa hàng Django tín hiệu xử lý như tài liệu tham khảo yếu bởi mặc định, vì vậy nếu xử lý của bạn là một địa phương chức năng, nó có thể được thu gom rác. Để ngăn chặn điều này, hãy chuyển yếu = False khi bạn gọi kết nối của tín hiệu().

Tôi chưa thể tìm thấy bất kỳ lý do nào vì lý do này là mặc định và tôi không hiểu tại sao bạn lại muốn một tín hiệu mà bạn đăng ký hoàn toàn biến mất. Vậy trường hợp sử dụng cho các tham chiếu yếu ở đây là gì? Và tại sao nó là mặc định?

Tôi nhận ra nó có thể không quan trọng trong 99% trường hợp, nhưng rõ ràng có điều gì đó tôi không hiểu ở đây, và tôi muốn biết nếu có bất kỳ "gotchas" rình rập có thể cắn tôi một ngày nào đó.

Trả lời

8

Trình xử lý tín hiệu được lưu trữ dưới dạng tham chiếu yếu để tránh đối tượng mà chúng tham chiếu không bị thu gom rác (ví dụ sau khi xóa bộ xử lý tín hiệu), chỉ vì tín hiệu vẫn đang bay xung quanh.

+0

Nhưng chắc chắn nếu trình xử lý tín hiệu bị ngắt kết nối rõ ràng, trình xử lý tín hiệu sẽ không được tham chiếu ở bất kỳ đâu và nó sẽ không ngăn chặn việc thu gom rác của bất kỳ thứ gì trong đó trường hợp. Dường như việc sử dụng các tham chiếu yếu sẽ chỉ tạo ra sự khác biệt khi tín hiệu là * không * ngắt kết nối rõ ràng, và tại sao bạn muốn tín hiệu bị ngắt kết nối nếu bạn không yêu cầu? –

+0

Bạn là đúng, do đó, để xử lý tín hiệu là rác được thu thập, không có tham chiếu yếu, bạn sẽ phải làm hai việc: xóa trình xử lý tín hiệu và ngắt kết nối tín hiệu. Điều này có thể không hiển nhiên đối với tất cả mọi người, vì vậy tôi nghĩ đây là lý do tại sao các tham chiếu yếu được sử dụng theo mặc định. –

+1

Xin lỗi vì quá dày đặc, nhưng tôi vẫn không hiểu. Tôi nghĩ rằng tôi hiểu những gì bạn có nghĩa là bằng cách "ngắt kết nối" một tín hiệu: Gọi phương thức 'ngắt kết nối' trên thể hiện' Signal', chuyển trong trình xử lý như một đối số. Nhưng những gì bạn có nghĩa là bằng cách "xóa" xử lý tín hiệu? –

4

Phương pháp ràng buộc giữ tham chiếu đến đối tượng mà chúng thuộc về (nếu không, chúng không thể điền self, xem Python documentation). Xét đoạn mã sau:

import gc 
class SomeLargeObject(object): 
    def on_foo(self): pass 

slo = SomeLargeObject() 
callbacks = [slo.on_foo] 

print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 
del slo 
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 
callbacks = [] 
print [o for o in gc.get_objects() if isinstance(o, SomeLargeObject)] 

Sản lượng:

[<__main__.SomeLargeObject object at 0x15001d0>] 
[<__main__.SomeLargeObject object at 0x15001d0>] 
[] 

Một điều quan trọng cần biết khi giữ weakrefs trên callbacks là bạn không thể weakref phương pháp ràng buộc trực tiếp, bởi vì họ luôn tạo ra một cách nhanh chóng:

>>> class SomeLargeObject(object): 
... def on_foo(self): pass 
>>> import weakref 
>>> def report(o): 
... print "about to collect" 
>>> slo = SomeLargeObject() 
>>> #second argument: function that is called when weakref'ed object is finalized 
>>> weakref.proxy(slo.on_foo, report) 
about to collect 
<weakproxy at 0x7f9abd3be208 to NoneType at 0x72ecc0> 
+0

Tôi đã lướt qua việc thực hiện Django và thấy có thực sự nỗ lực đặc biệt để cung cấp tài liệu tham khảo yếu để ràng buộc phương pháp. Nhưng làm thế nào về phương pháp unbound? Các tài liệu tham khảo cho họ được lưu giữ ở đâu?Điều gì sẽ kích hoạt bộ sưu tập rác của họ? Khi bạn xóa mô-đun nơi chúng được xác định? – hsribei

Các vấn đề liên quan