<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之旅 廣告
                ## 問題 你想通過改變實例創建方式來實現單例、緩存或其他類似的特性。 ## 解決方案 Python程序員都知道,如果你定義了一個類,就能像函數一樣的調用它來創建實例,例如: class Spam: def __init__(self, name): self.name = name a = Spam('Guido') b = Spam('Diana') 如果你想自定義這個步驟,你可以定義一個元類并自己實現 `__call__()` 方法。 為了演示,假設你不想任何人創建這個類的實例: class NoInstances(type): def __call__(self, *args, **kwargs): raise TypeError("Can't instantiate directly") # Example class Spam(metaclass=NoInstances): @staticmethod def grok(x): print('Spam.grok') 這樣的話,用戶只能調用這個類的靜態方法,而不能使用通常的方法來創建它的實例。例如: >>> Spam.grok(42) Spam.grok >>> s = Spam() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "example1.py", line 7, in __call__ raise TypeError("Can't instantiate directly") TypeError: Can't instantiate directly >>> 現在,假如你想實現單例模式(只能創建唯一實例的類),實現起來也很簡單: class Singleton(type): def __init__(self, *args, **kwargs): self.__instance = None super().__init__(*args, **kwargs) def __call__(self, *args, **kwargs): if self.__instance is None: self.__instance = super().__call__(*args, **kwargs) return self.__instance else: return self.__instance # Example class Spam(metaclass=Singleton): def __init__(self): print('Creating Spam') 那么Spam類就只能創建唯一的實例了,演示如下: >>> a = Spam() Creating Spam >>> b = Spam() >>> a is b True >>> c = Spam() >>> a is c True >>> 最后,假設你想創建8.25小節中那樣的緩存實例。下面我們可以通過元類來實現: import weakref class Cached(type): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.__cache = weakref.WeakValueDictionary() def __call__(self, *args): if args in self.__cache: return self.__cache[args] else: obj = super().__call__(*args) self.__cache[args] = obj return obj # Example class Spam(metaclass=Cached): def __init__(self, name): print('Creating Spam({!r})'.format(name)) self.name = name 然后我也來測試一下: >>> a = Spam('Guido') Creating Spam('Guido') >>> b = Spam('Diana') Creating Spam('Diana') >>> c = Spam('Guido') # Cached >>> a is b False >>> a is c # Cached value returned True >>> ## 討論 利用元類實現多種實例創建模式通常要比不使用元類的方式優雅得多。 假設你不使用元類,你可能需要將類隱藏在某些工廠函數后面。比如為了實現一個單例,你你可能會像下面這樣寫: class _Spam: def __init__(self): print('Creating Spam') _spam_instance = None def Spam(): global _spam_instance if _spam_instance is not None: return _spam_instance else: _spam_instance = _Spam() return _spam_instance 盡管使用元類可能會涉及到比較高級點的技術,但是它的代碼看起來會更加簡潔舒服,而且也更加直觀。 更多關于創建緩存實例、弱引用等內容,請參考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>

                              哎呀哎呀视频在线观看