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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 問題 你想要擴展函數中的某個閉包,允許它能訪問和修改函數的內部變量。 ## 解決方案 通常來講,閉包的內部變量對于外界來講是完全隱藏的。但是,你可以通過編寫訪問函數并將其作為函數屬性綁定到閉包上來實現這個目的。例如: def sample(): n = 0 # Closure function def func(): print('n=', n) # Accessor methods for n def get_n(): return n def set_n(value): nonlocal n n = value # Attach as function attributes func.get_n = get_n func.set_n = set_n return func 下面是使用的例子: >>> f = sample() >>> f() n= 0 >>> f.set_n(10) >>> f() n= 10 >>> f.get_n() 10 >>> ## 討論 為了說明清楚它如何工作的,有兩點需要解釋一下。首先,`nonlocal` 聲明可以讓我們編寫函數來修改內部變量的值。其次,函數屬性允許我們用一種很簡單的方式將訪問方法綁定到閉包函數上,這個跟實例方法很像(盡管并沒有定義任何類)。 還可以進一步的擴展,讓閉包模擬類的實例。你要做的僅僅是復制上面的內部函數到一個字典實例中并返回它即可。例如: import sys class ClosureInstance: def __init__(self, locals=None): if locals is None: locals = sys._getframe(1).f_locals # Update instance dictionary with callables self.__dict__.update((key,value) for key, value in locals.items() if callable(value) ) # Redirect special methods def __len__(self): return self.__dict__['__len__']() # Example use def Stack(): items = [] def push(item): items.append(item) def pop(): return items.pop() def __len__(): return len(items) return ClosureInstance() 下面是一個交互式會話來演示它是如何工作的: >>> s = Stack() >>> s <__main__.ClosureInstance object at 0x10069ed10> >>> s.push(10) >>> s.push(20) >>> s.push('Hello') >>> len(s) 3 >>> s.pop() 'Hello' >>> s.pop() 20 >>> s.pop() 10 >>> 有趣的是,這個代碼運行起來會比一個普通的類定義要快很多。你可能會像下面這樣測試它跟一個類的性能對比: class Stack2: def __init__(self): self.items = [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def __len__(self): return len(self.items) 如果這樣做,你會得到類似如下的結果: >>> from timeit import timeit >>> # Test involving closures >>> s = Stack() >>> timeit('s.push(1);s.pop()', 'from __main__ import s') 0.9874754269840196 >>> # Test involving a class >>> s = Stack2() >>> timeit('s.push(1);s.pop()', 'from __main__ import s') 1.0707052160287276 >>> 結果顯示,閉包的方案運行起來要快大概8%,大部分原因是因為對實例變量的簡化訪問,閉包更快是因為不會涉及到額外的self變量。 Raymond Hettinger對于這個問題設計出了更加難以理解的改進方案。不過,你得考慮下是否真的需要在你代碼中這樣做,而且它只是真實類的一個奇怪的替換而已,例如,類的主要特性如繼承、屬性、描述器或類方法都是不能用的。并且你要做一些其他的工作才能讓一些特殊方法生效(比如上面 `ClosureInstance` 中重寫過的 `__len__()` 實現。) 最后,你可能還會讓其他閱讀你代碼的人感到疑惑,為什么它看起來不像一個普通的類定義呢?(當然,他們也想知道為什么它運行起來會更快)。盡管如此,這對于怎樣訪問閉包的內部變量也不失為一個有趣的例子。 總體上講,在配置的時候給閉包添加方法會有更多的實用功能,比如你需要重置內部狀態、刷新緩沖區、清除緩存或其他的反饋機制的時候。
                  <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>

                              哎呀哎呀视频在线观看