<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 問題 你想創建一個新的擁有一些額外功能的實例屬性類型,比如類型檢查。 ## 解決方案 如果你想創建一個全新的實例屬性,可以通過一個描述器類的形式來定義它的功能。下面是一個例子: # Descriptor attribute for an integer type-checked attribute class Integer: def __init__(self, name): self.name = name def __get__(self, instance, cls): if instance is None: return self else: return instance.__dict__[self.name] def __set__(self, instance, value): if not isinstance(value, int): raise TypeError('Expected an int') instance.__dict__[self.name] = value def __delete__(self, instance): del instance.__dict__[self.name] 一個描述器就是一個實現了三個核心的屬性訪問操作(get, set, delete)的類,分別為 `__get__()` 、`__set__()` 和 `__delete__()` 這三個特殊的方法。這些方法接受一個實例作為輸入,之后相應的操作實例底層的字典。 為了使用一個描述器,需將這個描述器的實例作為類屬性放到一個類的定義中。例如: class Point: x = Integer('x') y = Integer('y') def __init__(self, x, y): self.x = x self.y = y 當你這樣做后,所有隊描述器屬性(比如x或y)的訪問會被`__get__()` 、`__set__()` 和 `__delete__()` 方法捕獲到。例如: >>> p = Point(2, 3) >>> p.x # Calls Point.x.__get__(p,Point) 2 >>> p.y = 5 # Calls Point.y.__set__(p, 5) >>> p.x = 2.3 # Calls Point.x.__set__(p, 2.3) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "descrip.py", line 12, in __set__ raise TypeError('Expected an int') TypeError: Expected an int >>> 作為輸入,描述器的每一個方法會接受一個操作實例。為了實現請求操作,會相應的操作實例底層的字典(__dict__屬性)。描述器的 `self.name` 屬性存儲了在實例字典中被實際使用到的key。 ## 討論 描述器可實現大部分Python類特性中的底層魔法,包括 `@classmethod` 、`@staticmethod` 、`@property` ,甚至是 `__slots__` 特性。 通過定義一個描述器,你可以在底層捕獲核心的實例操作(get, set, delete),并且可完全自定義它們的行為。這是一個強大的工具,有了它你可以實現很多高級功能,并且它也是很多高級庫和框架中的重要工具之一。 描述器的一個比較困惑的地方是它只能在類級別被定義,而不能為每個實例單獨定義。因此,下面的代碼是無法工作的: # Does NOT work class Point: def __init__(self, x, y): self.x = Integer('x') # No! Must be a class variable self.y = Integer('y') self.x = x self.y = y 同時,`__get__()` 方法實現起來比看上去要復雜得多: # Descriptor attribute for an integer type-checked attribute class Integer: def __get__(self, instance, cls): if instance is None: return self else: return instance.__dict__[self.name] `__get__()` 看上去有點復雜的原因歸結于實例變量和類變量的不同。如果一個描述器被當做一個類變量來訪問,那么 `instance` 參數被設置成 `None` 。這種情況下,標準做法就是簡單的返回這個描述器本身即可(盡管你還可以添加其他的自定義操作)。例如: >>> p = Point(2,3) >>> p.x # Calls Point.x.__get__(p, Point) 2 >>> Point.x # Calls Point.x.__get__(None, Point) <__main__.Integer object at 0x100671890> >>> 描述器通常是那些使用到裝飾器或元類的大型框架中的一個組件。同時它們的使用也被隱藏在后面。舉個例子,下面是一些更高級的基于描述器的代碼,并涉及到一個類裝飾器: # Descriptor for a type-checked attribute class Typed: def __init__(self, name, expected_type): self.name = name self.expected_type = expected_type def __get__(self, instance, cls): if instance is None: return self else: return instance.__dict__[self.name] def __set__(self, instance, value): if not isinstance(value, self.expected_type): raise TypeError('Expected ' + str(self.expected_type)) instance.__dict__[self.name] = value def __delete__(self, instance): del instance.__dict__[self.name] # Class decorator that applies it to selected attributes def typeassert(**kwargs): def decorate(cls): for name, expected_type in kwargs.items(): # Attach a Typed descriptor to the class setattr(cls, name, Typed(name, expected_type)) return cls return decorate # Example use @typeassert(name=str, shares=int, price=float) class Stock: def __init__(self, name, shares, price): self.name = name self.shares = shares self.price = price 最后要指出的一點是,如果你只是想簡單的自定義某個類的單個屬性訪問的話就不用去寫描述器了。這種情況下使用8.6小節介紹的property技術會更加容易。當程序中有很多重復代碼的時候描述器就很有用了(比如你想在你代碼的很多地方使用描述器提供的功能或者將它作為一個函數庫特性)。
                  <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>

                              哎呀哎呀视频在线观看