Tôi có một số mã nơi thể hiện của lớp có mẹ < -> con tham khảo với nhau, ví dụ:Làm thế nào và khi nào thì thích hợp sử dụng weakref bằng Python
class Node(object):
def __init__(self):
self.parent = None
self.children = {}
def AddChild(self, name, child):
child.parent = self
self.children[name] = child
def Run():
root, c1, c2 = Node(), Node(), Node()
root.AddChild("first", c1)
root.AddChild("second", c2)
Run()
tôi nghĩ điều này tạo ra tham chiếu vòng tròn như vậy mà root
, c1
và c2
sẽ không được giải phóng sau khi Run() được hoàn tất, đúng không ?. Vậy làm cách nào để họ được tự do? Tôi nghĩ tôi có thể làm điều gì đó như root.children.clear()
hoặc self.parent = None
- nhưng nếu tôi không biết khi nào thì làm như vậy?
Đây có phải là thời điểm thích hợp để sử dụng mô-đun weakref không? Cái gì, chính xác, tôi có suy yếu không? thuộc tính parent
? Thuộc tính children
? Toàn bộ vật thể? Tất cả những điều trên? Tôi thấy nói về WeakKeyDictionary và weakref.proxy, nhưng nó không rõ ràng với tôi làm thế nào họ nên được sử dụng, nếu ở tất cả, trong trường hợp này.
Đây cũng là trên python2.4 (không thể nâng cấp).
Cập nhật: Ví dụ và Tóm tắt
gì phản đối weakref-IFY phụ thuộc vào đối tượng có thể sống mà không có người kia, và những gì đối tượng phụ thuộc vào nhau. Đối tượng tồn tại lâu nhất nên chứa weakrefs đối với các đối tượng sống ngắn hơn. Tương tự như vậy, weakrefs không nên được thực hiện cho các phụ thuộc - nếu chúng là, phụ thuộc có thể âm thầm biến mất mặc dù nó vẫn còn cần thiết.
Nếu, ví dụ, bạn có một cấu trúc cây, root
, có trẻ em, kids
, nhưng có thể tồn tại mà không trẻ em, sau đó đối tượng root
nên sử dụng weakrefs cho kids
của nó. Đây cũng là trường hợp nếu đối tượng con phụ thuộc vào sự tồn tại của đối tượng cha. Bên dưới, đối tượng con yêu cầu một phụ huynh để tính toán độ sâu của nó, do đó mạnh mẽ cho số parent
. Tuy nhiên, các thành viên của thuộc tính kids
là tùy chọn, do đó, weakrefs được sử dụng để ngăn chặn tham chiếu vòng tròn.
class Node:
def __init__(self)
self.parent = None
self.kids = weakref.WeakValueDictionary()
def GetDepth(self):
root, depth = self, 0
while root:
depth += 1
root = root.parent
return depth
root = Node()
root.kids["one"] = Node()
root.kids["two"] = Node()
# do what you will with root or sub-trees of it.
Để lật mối quan hệ xung quanh, chúng tôi có nội dung như bên dưới. Ở đây, các lớp học Facade
yêu cầu một cá thể Subsystem
để hoạt động, do đó, chúng sử dụng một tham chiếu mạnh mẽ cho hệ thống con mà họ cần. Tuy nhiên, Subsystem
s không yêu cầu Facade
hoạt động. Subsystem
s chỉ cung cấp một cách để thông báo Facade
về các hành động của nhau.
class Facade:
def __init__(self, subsystem)
self.subsystem = subsystem
subsystem.Register(self)
class Subsystem:
def __init__(self):
self.notify = []
def Register(self, who):
self.notify.append(weakref.proxy(who))
sub = Subsystem()
f1 = CliFacade(sub)
f2 = WebFacade(sub)
# Go on to reading from POST, stdin, etc
Ngoài ra, nếu bạn chắc chắn bạn sẽ không cần đến gc tuần hoàn, bạn có thể tắt nó để tăng hiệu suất nhỏ . –
Cảm ơn, Alex. Có lý do cụ thể nào để suy yếu 'trẻ em' thay vì' cha mẹ'? Liệu hiệu ứng có giống nhau không? Điều gì sẽ xảy ra nếu 'cha mẹ' cũng yếu ớt? Trong trường hợp của một danh sách liên kết kép, nên 'prev',' next', hoặc cả hai đều là weakrefs? –
Đây là gợi ý không tốt. Tất cả trẻ em trong ví dụ này sẽ bị hủy ngay sau khi trở về từ 'Run()'. Nói chung, bạn hầu như luôn luôn ràng buộc một gốc của cấu trúc thành biến, do đó, đúng cách là sử dụng 'weakref' cho' parent', nhưng không phải là 'children'. –