<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 問題 你的程序創建了很多循環引用數據結構(比如樹、圖、觀察者模式等),你碰到了內存管理難題。 ## 解決方案 一個簡單的循環引用數據結構例子就是一個樹形結構,雙親節點有指針指向孩子節點,孩子節點又返回來指向雙親節點。這種情況下,可以考慮使用 `weakref` 庫中的弱引用。例如: import weakref class Node: def __init__(self, value): self.value = value self._parent = None self.children = [] def __repr__(self): return 'Node({!r:})'.format(self.value) # property that manages the parent as a weak-reference @property def parent(self): return None if self._parent is None else self._parent() @parent.setter def parent(self, node): self._parent = weakref.ref(node) def add_child(self, child): self.children.append(child) child.parent = self 這種是想方式允許parent靜默終止。例如: >>> root = Node('parent') >>> c1 = Node('child') >>> root.add_child(c1) >>> print(c1.parent) Node('parent') >>> del root >>> print(c1.parent) None >>> ## 討論 循環引用的數據結構在Python中是一個很棘手的問題,因為正常的垃圾回收機制不能適用于這種情形。例如考慮如下代碼: # Class just to illustrate when deletion occurs class Data: def __del__(self): print('Data.__del__') # Node class involving a cycle class Node: def __init__(self): self.data = Data() self.parent = None self.children = [] def add_child(self, child): self.children.append(child) child.parent = self 下面我們使用這個代碼來做一些垃圾回收試驗: >>> a = Data() >>> del a # Immediately deleted Data.__del__ >>> a = Node() >>> del a # Immediately deleted Data.__del__ >>> a = Node() >>> a.add_child(Node()) >>> del a # Not deleted (no message) >>> 可以看到,最后一個的刪除時打印語句沒有出現。原因是Python的垃圾回收機制是基于簡單的引用計數。當一個對象的引用數變成0的時候才會立即刪除掉。而對于循環引用這個條件永遠不會成立。因此,在上面例子中最后部分,父節點和孩子節點互相擁有對方的引用,導致每個對象的引用計數都不可能變成0。 Python有另外的垃圾回收器來專門針對循環引用的,但是你永遠不知道它什么時候會觸發。另外你還可以手動的觸發它,但是代碼看上去很挫: >>> import gc >>> gc.collect() # Force collection Data.__del__ Data.__del__ >>> 如果循環引用的對象自己還定義了自己的 `__del__()` 方法,那么會讓情況變得更糟糕。假設你像下面這樣給Node定義自己的 `__del__()` 方法: # Node class involving a cycle class Node: def __init__(self): self.data = Data() self.parent = None self.children = [] def add_child(self, child): self.children.append(child) child.parent = self # NEVER DEFINE LIKE THIS. # Only here to illustrate pathological behavior def __del__(self): del self.data del.parent del.children 這種情況下,垃圾回收永遠都不會去回收這個對象的,還會導致內存泄露。如果你試著去運行它會發現,`Data.__del__` 消息永遠不會出現了,甚至在你強制內存回收時: >>> a = Node() >>> a.add_child(Node() >>> del a # No message (not collected) >>> import gc >>> gc.collect() # No message (not collected) >>> 弱引用消除了引用循環的這個問題,本質來講,弱引用就是一個對象指針,它不會增加它的引用計數。你可以通過 `weakref` 來創建弱引用。例如: >>> import weakref >>> a = Node() >>> a_ref = weakref.ref(a) >>> a_ref <weakref at 0x100581f70; to 'Node' at 0x1005c5410> >>> 為了訪問弱引用所引用的對象,你可以像函數一樣去調用它即可。如果那個對象還存在就會返回它,否則就返回一個None。由于原始對象的引用計數沒有增加,那么就可以去刪除它了。例如; >>> print(a_ref()) <__main__.Node object at 0x1005c5410> >>> del a Data.__del__ >>> print(a_ref()) None >>> 通過這里演示的弱引用技術,你會發現不再有循環引用問題了,一旦某個節點不被使用了,垃圾回收器立即回收它。你還能參考8.25小節關于弱引用的另外一個例子。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看