<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之旅 廣告
                ## 問題 你想在類被定義的時候就初始化一部分類的成員,而不是要等到實例被創建后。 ## 解決方案 在類定義時就執行初始化或設置操作是元類的一個典型應用場景。本質上講,一個元類會在定義時被觸發,這時候你可以執行一些額外的操作。 下面是一個例子,利用這個思路來創建類似于 `collections` 模塊中的命名元組的類: import operator class StructTupleMeta(type): def __init__(cls, *args, **kwargs): super().__init__(*args, **kwargs) for n, name in enumerate(cls._fields): setattr(cls, name, property(operator.itemgetter(n))) class StructTuple(tuple, metaclass=StructTupleMeta): _fields = [] def __new__(cls, *args): if len(args) != len(cls._fields): raise ValueError('{} arguments required'.format(len(cls._fields))) return super().__new__(cls,args) 這段代碼可以用來定義簡單的基于元組的數據結構,如下所示: class Stock(StructTuple): _fields = ['name', 'shares', 'price'] class Point(StructTuple): _fields = ['x', 'y'] 下面演示它如何工作: >>> s = Stock('ACME', 50, 91.1) >>> s ('ACME', 50, 91.1) >>> s[0] 'ACME' >>> s.name 'ACME' >>> s.shares * s.price 4555.0 >>> s.shares = 23 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can't set attribute >>> ## 討論 這一小節中,類 `StructTupleMeta` 獲取到類屬性 `_fields` 中的屬性名字列表,然后將它們轉換成相應的可訪問特定元組槽的方法。函數 `operator.itemgetter()` 創建一個訪問器函數,然后 `property()` 函數將其轉換成一個屬性。 本節最難懂的部分是知道不同的初始化步驟是什么時候發生的。`StructTupleMeta` 中的 `__init__()` 方法只在每個類被定義時被調用一次。`cls` 參數就是那個被定義的類。實際上,上述代碼使用了 `_fields` 類變量來保存新的被定義的類,然后給它再添加一點新的東西。 `StructTuple` 類作為一個普通的基類,供其他使用者來繼承。這個類中的 `__new__()` 方法用來構造新的實例。這里使用 `__new__()` 并不是很常見,主要是因為我們要修改元組的調用簽名,使得我們可以像普通的實例調用那樣創建實例。就像下面這樣: s = Stock('ACME', 50, 91.1) # OK s = Stock(('ACME', 50, 91.1)) # Error 跟 `__init__()` 不同的是,`__new__()` 方法在實例被創建之前被觸發。由于元組是不可修改的,所以一旦它們被創建了就不可能對它做任何改變。而 `__init__()` 會在實例創建的最后被觸發,這樣的話我們就可以做我們想做的了。這也是為什么 `__new__()` 方法已經被定義了。 盡管本節很短,還是需要你能仔細研讀,深入思考Python類是如何被定義的,實例是如何被創建的,還有就是元類和類的各個不同的方法究竟在什么時候被調用。 [PEP 422](http://www.python.org/dev/peps/pep-0422) 提供了一個解決本節問題的另外一種方法。但是,截止到我寫這本書的時候,它還沒被采納和接受。盡管如此,如果你使用的是Python 3.3或更高的版本,那么還是值得去看一下的。
                  <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>

                              哎呀哎呀视频在线观看