最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中l(wèi)azy property的兩種方法小結(jié)

 更新時間:2025年01月17日 10:15:45   作者:Python熱愛者  
本文介紹了Python中實現(xiàn)延遲屬性lazyproperty的兩種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

我們都知道,在Python的類中,__dict__保存了一個對象所有的屬性,如下面的例子,我們建立了一個Circle的對象,對象的字典中保存著半徑radius 這個k-v值:

class Circle(object):
    def __init__(self,radius):
        self.radius = radius
    
c = Circle(2.5)
print(c.__dict__)
 
#{'radius': 2.5}

對于類中的方法,我們有時候希望它可以像屬性一樣被調(diào)用,這時候我們通常給類的方法添加@property修飾符:

class Circle(object):
    def __init__(self,radius):
        self.radius = radius
    @property
    def area(self):
        print("calculate area")
        return 3.14 * self.radius * 2
circle = Circle(4)
print(circle.area)
 
#calculate area
#25.12

但是這么做,雖然area可以當(dāng)作一個屬性訪問,但是并不是真正的變成了一個屬性,同時,我們每次調(diào)用circle.area,都會從頭到尾執(zhí)行一遍函數(shù),我們來看下面的例子:

class Circle(object):
    def __init__(self,radius):
        self.radius = radius
    @property
    def area(self):
        print("calculate area")
        return 3.14 * self.radius * 2
    
c = Circle(4) 
print(c.__dict__)
print(c.area)
print(c.area)
print(c.__dict__)

輸出為:

{'radius': 4}
calculate area
25.12
calculate area
25.12
{'radius': 4}

可以發(fā)現(xiàn):

  • 每次執(zhí)行circle.area,整個函數(shù)流程都會被執(zhí)行一次
  • 同時area也沒有真正變成對象的屬性,dict中并沒有area

深入

那么我們有沒有辦法把一個類中的函數(shù)真正變成對象的屬性,同時只有在第一次調(diào)用時進(jìn)行一次計算,而之后每次調(diào)用不會重復(fù)計算呢?這就是Python中的lazy property。

本文介紹兩種方法。一種是使用python描述符,另一種是使用python修飾符。

1、使用python描述符

class lazy(object):
    def __init__(self, func):
        self.func = func
 
    def __get__(self, instance, cls):
        val = self.func(instance)
        setattr(instance, self.func.__name__, val)
        return val
 
class Circle(object): 
  def __init__(self, radius): 
    self.radius = radius 
  
  @lazy
  def area(self): 
    print("calculate area")
    return 3.14 * self.radius ** 2
 
c = Circle(4) 
print('before calculate area')
print(c.__dict__)
print(c.area)
print(c.area)
print('after calculate area')
print(c.__dict__)
c.radius = 5
print(c.__dict__)
print(c.area)

輸出為:

before calculate area
{'radius': 4}
calculate area
50.24
50.24
after calculate area
{'radius': 4, 'area': 50.24}
{'radius': 5, 'area': 50.24}
50.24
{'radius': 5, 'area': 50.24}

可以看到,area只在第一次調(diào)用時計算了一次,同時在調(diào)用以后area變成了對象的一個屬性,同時值并不隨半徑的變化而變化。

在這里,lazy類有__get__方法,說明是個描述器,第一次執(zhí)行c.area的時候,因為順序問題,先去c.__dict__中找,沒找到,就去類空間找,在類Circle中,有area()方法,于是就被__get__攔截。

__get__中,調(diào)用實例的area()方法算出結(jié)果,并動態(tài)給實例添加個同名屬性把結(jié)果賦給它,即加到c.__dict__中去。

再次執(zhí)行c.area的時候,先去c.__dict__找,因為此時已經(jīng)有了,就不會經(jīng)過area()方法和__get__了。

2、使用python修飾符

def lazy_property(func):
    attr_name = "_lazy_" + func.__name__
 
    @property
    def _lazy_property(instance):
        if not hasattr(instance, attr_name):
            setattr(instance, attr_name, func(instance))
        return getattr(instance, attr_name)
 
    return _lazy_property
 
class Circle(object): 
  def __init__(self, radius): 
    self.radius = radius 
  
  @lazy_property
  def area(self): 
    return 3.14 * self.radius ** 2
 
c = Circle(4) 
print('before calculate area')
print(c.__dict__)
print(c.area)
print(c.area)
print('after calculate area')
print(c.__dict__)
c.radius = 5
print(c.__dict__)
print(c.area)

輸出為:

before calculate area
{'radius': 4}
50.24
50.24
after calculate area
{'radius': 4, '_lazy_area': 50.24}
{'radius': 5, '_lazy_area': 50.24}
50.24

可以看到,area只在第一次調(diào)用時計算了一次,同時在調(diào)用以后area變成了對象的一個屬性,同時值并不隨半徑的變化而變化。

到此這篇關(guān)于Python中l(wèi)azy property的兩種方法小結(jié)的文章就介紹到這了,更多相關(guān)Python lazy property內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python 中創(chuàng)建 PostgreSQL 數(shù)據(jù)庫連接池

    Python 中創(chuàng)建 PostgreSQL 數(shù)據(jù)庫連接池

    這篇文章主要介紹了Python 中創(chuàng)建 PostgreSQL 數(shù)據(jù)庫連接池,Python 連接 PostgreSQL 是主要有兩個包, py-postgresql 和 psycopg2 , 而本文的實例將使用后者,感興趣的小伙伴可以參考一下
    2021-10-10
  • python subprocess pipe 實時輸出日志的操作

    python subprocess pipe 實時輸出日志的操作

    這篇文章主要介紹了python subprocess pipe 實時輸出日志的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • pycharm激活方法到2099年(激活流程)

    pycharm激活方法到2099年(激活流程)

    這篇文章主要介紹了pycharm激活方法到2099年,文末給大家提到了idea和pycharm最新版激活方法,非常不錯對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Python腳本實現(xiàn)音頻和視頻格式轉(zhuǎn)換

    Python腳本實現(xiàn)音頻和視頻格式轉(zhuǎn)換

    這篇文章主要為大家詳細(xì)介紹了Python如何通過腳本實現(xiàn)音頻和視頻格式轉(zhuǎn)換,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • python發(fā)布模塊的步驟分享

    python發(fā)布模塊的步驟分享

    這篇文章主要介紹了python發(fā)布模塊的步驟,需要的朋友可以參考下
    2014-02-02
  • 使用Cython中prange函數(shù)實現(xiàn)for循環(huán)的并行

    使用Cython中prange函數(shù)實現(xiàn)for循環(huán)的并行

    Cython中提供了一個prange函數(shù),專門用于循環(huán)的并行執(zhí)行。這個 prange的特殊功能是Cython獨(dú)一無二的,并且prange只能與for循環(huán)搭配使用,不能獨(dú)立存在。本文就將使用 prange 實現(xiàn) for 循環(huán)的并行,感興趣的可以了解一下
    2022-08-08
  • python對ip地址進(jìn)行排序、分類的方法詳解

    python對ip地址進(jìn)行排序、分類的方法詳解

    這篇文章主要介紹了python對ip地址進(jìn)行排序、分類的方法詳解,IP協(xié)議全稱為“網(wǎng)際互連協(xié)議Internet?Protocol”,IP協(xié)議是TCP/IP體系中的網(wǎng)絡(luò)層協(xié)議,需要的朋友可以參考下
    2023-07-07
  • python對二維數(shù)組賦值問題

    python對二維數(shù)組賦值問題

    這篇文章主要介紹了python對二維數(shù)組賦值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python實現(xiàn)將HTML轉(zhuǎn)為PDF/圖片/XML/XPS格式

    Python實現(xiàn)將HTML轉(zhuǎn)為PDF/圖片/XML/XPS格式

    網(wǎng)頁內(nèi)容是信息傳播的主要形式之一,這篇文章主要和大家介紹了如何使用Python實現(xiàn)將HTML分別轉(zhuǎn)為PDF/圖片/XML/XPS格式等,需要的可以參考下
    2024-03-03
  • 解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題

    解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題

    這篇文章主要介紹了解決pytorch讀取自制數(shù)據(jù)集出現(xiàn)過的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-05-05

最新評論

新竹县| 论坛| 海阳市| 乐清市| 松潘县| 南江县| 平邑县| 万年县| 平阳县| 高平市| 门头沟区| 城步| 呼图壁县| 周宁县| 肃宁县| 红原县| 新泰市| 桂林市| 遂平县| 定襄县| 察哈| 兴隆县| 岚皋县| 湖州市| 若羌县| 安阳县| 屯门区| 淮阳县| 襄汾县| 成武县| 从江县| 杨浦区| 崇信县| 普陀区| 丰城市| 甘肃省| 平顺县| 确山县| 名山县| 元江| 分宜县|