<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # Python `@property`裝飾器 > 原文: [https://www.programiz.com/python-programming/property](https://www.programiz.com/python-programming/property) #### 在本教程中,您將學習 Python `@property`裝飾器。 在面向對象程序設計中使用獲取器和設置器的 pythonic 方式。 Python 編程為我們提供了一個內置的`@property`裝飾器,使面向對象編程中的獲取器和設置器的使用變得更加容易。 在詳細介紹`@property`裝飾器是什么之前,讓我們首先了解一下為什么首先需要使用它。 * * * ## 沒有獲取器和設置器的類 讓我們假設我們決定制作一個[類](/python-programming/class),該類存儲以攝氏度為單位的溫度。 它還將實現一種將溫度轉換為華氏度的方法。 一種方法如下: ```py class Celsius: def __init__(self, temperature = 0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 ``` 我們可以根據需要創建對象,并根據需要操縱`temperature`屬性: ```py # Basic method of setting and getting attributes in Python class Celsius: def __init__(self, temperature=0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # Create a new object human = Celsius() # Set the temperature human.temperature = 37 # Get the temperature attribute print(human.temperature) # Get the to_fahrenheit method print(human.to_fahrenheit()) ``` **輸出** ```py 37 98.60000000000001 ``` 轉換為華氏溫度時,多余的小數位是由于浮點運算錯誤。 要了解更多信息,請訪問 [Python 浮點算術錯誤](/python-programming/numbers#dec)。 每當我們如上所述分配或檢索任何對象屬性(如`temperature`)時,Python 都會在對象的內置`__dict__`字典屬性中進行搜索。 ```py >>> human.__dict__ {'temperature': 37} ``` 因此,`man.temperature`在內部變為`man.__dict__['temperature']`。 * * * ## 使用獲取器和設置器 假設我們要擴展上面定義的`Celsius`類的可用性。 我們知道任何物體的溫度都不能低于 -273.15 攝氏度(熱力學中的絕對零) 讓我們更新代碼以實現此值約束。 上述限制的一個明顯解決方案是隱藏屬性`temperature`(將其設為私有),并定義新的獲取器和設置器方法來對其進行操作。 可以按以下步驟完成: ```py # Making Getters and Setter methods class Celsius: def __init__(self, temperature=0): self.set_temperature(temperature) def to_fahrenheit(self): return (self.get_temperature() * 1.8) + 32 # getter method def get_temperature(self): return self._temperature # setter method def set_temperature(self, value): if value < -273.15: raise ValueError("Temperature below -273.15 is not possible.") self._temperature = value ``` 如我們所見,以上方法引入了兩個新的`get_temperature()`和`set_temperature()`方法。 此外,`temperature`被替換為`_temperature`。 開頭的下劃線`_`用于表示 Python 中的私有變量。 * * * 現在,讓我們使用以下實現: ```py # Making Getters and Setter methods class Celsius: def __init__(self, temperature=0): self.set_temperature(temperature) def to_fahrenheit(self): return (self.get_temperature() * 1.8) + 32 # getter method def get_temperature(self): return self._temperature # setter method def set_temperature(self, value): if value < -273.15: raise ValueError("Temperature below -273.15 is not possible.") self._temperature = value # Create a new object, set_temperature() internally called by __init__ human = Celsius(37) # Get the temperature attribute via a getter print(human.get_temperature()) # Get the to_fahrenheit method, get_temperature() called by the method itself print(human.to_fahrenheit()) # new constraint implementation human.set_temperature(-300) # Get the to_fahreheit method print(human.to_fahrenheit()) ``` **輸出**: ```py 37 98.60000000000001 Traceback (most recent call last): File "<string>", line 30, in <module> File "<string>", line 16, in set_temperature ValueError: Temperature below -273.15 is not possible. ``` 此更新成功實現了新限制。 我們不再被允許將溫度設置為低于-273.15 攝氏度。 **注意**:私有變量實際上在 Python 中不存在。 只需遵循一些規范。 語言本身沒有任何限制。 ```py >>> human._temperature = -300 >>> human.get_temperature() -300 ``` 但是,上述更新的更大問題是,實現我們上一類的所有程序都必須將其代碼從`obj.temperature`修改為`obj.get_temperature()`,并將所有表達式從`obj.temperature = val`修改為`obj.set_temperature(val)`。 在處理成千上萬行代碼時,這種重構可能會引起問題。 總而言之,我們的新更新不向后兼容。 這是`@property`搶救的地方。 * * * ## 屬性類 解決上述問題的一種 Python 方法是使用`property`類。 這是我們如何更新代碼的方法: ```py # using property class class Celsius: def __init__(self, temperature=0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # getter def get_temperature(self): print("Getting value...") return self._temperature # setter def set_temperature(self, value): print("Setting value...") if value < -273.15: raise ValueError("Temperature below -273.15 is not possible") self._temperature = value # creating a property object temperature = property(get_temperature, set_temperature) ``` 我們在`get_temperature()`和`set_temperature()`內部添加了`print()`函數,以清楚地觀察它們正在執行。 代碼的最后一行創建一個屬性對象`temperature`。 簡而言之,屬性將一些代碼(`get_temperature`和`set_temperature`)附加到成員屬性訪問(`temperature`)。 讓我們使用以下更新代碼: ```py # using property class class Celsius: def __init__(self, temperature=0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 # getter def get_temperature(self): print("Getting value...") return self._temperature # setter def set_temperature(self, value): print("Setting value...") if value < -273.15: raise ValueError("Temperature below -273.15 is not possible") self._temperature = value # creating a property object temperature = property(get_temperature, set_temperature) human = Celsius(37) print(human.temperature) print(human.to_fahrenheit()) human.temperature = -300 ``` **輸出**: ```py Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): File "<string>", line 31, in <module> File "<string>", line 18, in set_temperature ValueError: Temperature below -273 is not possible ``` 如我們所見,任何檢索`temperature`值的代碼都會自動調用`get_temperature()`,而不是字典(__dict__)查找。 類似地,任何為`temperature`賦值的代碼都會自動調用`set_temperature()`。 我們甚至可以在上面看到即使創建對象時也調用了`set_temperature()`。 ```py >>> human = Celsius(37) Setting value... ``` **你能猜出為什么嗎?** 原因是在創建對象時,將調用`__init__()`方法。 該方法具有行`self.temperature = temperature`。 該表達式自動調用`set_temperature()`。 同樣,任何訪問`c.temperature`都會自動調用`get_temperature()`。 這就是財產的作用。 這里還有一些例子。 ```py >>> human.temperature Getting value 37 >>> human.temperature = 37 Setting value >>> c.to_fahrenheit() Getting value 98.60000000000001 ``` 通過使用`property`,我們可以看到在實現值約束時不需要修改。 因此,我們的實現是向后兼容的。 **注意**:實際溫度值存儲在私有`_temperature`變量中。`temperature`屬性是為該私有變量提供接口的屬性對象。 * * * ## `@property`裝飾器 在 Python 中,`property()`是一個內置函數,可創建并返回`property`對象。 該函數的語法為: ```py property(fget=None, fset=None, fdel=None, doc=None) ``` 哪里, * `fget`是獲取屬性值的函數 * `fset`是設置屬性值的函數 * `fdel`是刪除屬性的函數 * `doc`是一個字符串(如注釋) 從實現中可以看出,這些函數參數是可選的。 因此,可以簡單地如下創建屬性對象。 ```py >>> property() <property object at 0x0000000003239B38> ``` 屬性對象具有`getter()`,`setter()`和`deleter()`三種方法,以便在以后指定`fget`,`fset`和`fdel`。 這意味著,該行: ```py temperature = property(get_temperature,set_temperature) ``` 可以細分為: ```py # make empty property temperature = property() # assign fget temperature = temperature.getter(get_temperature) # assign fset temperature = temperature.setter(set_temperature) ``` 這兩段代碼是等效的。 熟悉 [Python 裝飾器](/python-programming/decorator)的程序員可以認識到上述構造可以實現為裝飾器。 我們甚至無法定義名稱`get_temperature`和`set_temperature`,因為它們是不必要的,并污染了類名稱空間。 為此,我們在定義獲取器和設置器函數的同時重用`temperature`名稱。 讓我們看一下如何將其實現為裝飾器: ```py # Using @property decorator class Celsius: def __init__(self, temperature=0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 @property def temperature(self): print("Getting value...") return self._temperature @temperature.setter def temperature(self, value): print("Setting value...") if value < -273.15: raise ValueError("Temperature below -273 is not possible") self._temperature = value # create an object human = Celsius(37) print(human.temperature) print(human.to_fahrenheit()) coldest_thing = Celsius(-300) ``` **輸出**: ```py Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): File "<string>", line 29, in <module> File "<string>", line 4, in __init__ File "<string>", line 18, in temperature ValueError: Temperature below -273 is not possible ``` 上面的實現是簡單而有效的。 建議使用`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>

                              哎呀哎呀视频在线观看