欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2025年01月17日 10:15:45   作者:Python熱愛者  
本文介紹了Python中實現(xiàn)延遲屬性lazyproperty的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學(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)用時進行一次計算,而之后每次調(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處理文件目錄的相關(guān)方法

    詳解使用Python處理文件目錄的相關(guān)方法

    這篇文章主要介紹了使用Python處理文件目錄的相關(guān)方法,使用到了os模塊,需要的朋友可以參考下
    2015-10-10
  • Python實現(xiàn)批量提取PPT中的文字

    Python實現(xiàn)批量提取PPT中的文字

    這篇文章主要為大家詳細介紹了如何使用Python中的pptx和docx庫來將PPT中的文字提取到Word中,文中的示例代碼講解詳細,有需要的可以參考下
    2024-03-03
  • Python如何寫入Pandas DataFrame到CSV文件

    Python如何寫入Pandas DataFrame到CSV文件

    Pandas是一個功能強大的Python數(shù)據(jù)分析庫,常用于處理和分析數(shù)據(jù),CSV文件是一種廣泛使用的數(shù)據(jù)交換格式,Pandas通過to_csv方法支持將DataFrame寫入CSV文件,此方法允許用戶指定分隔符、編碼和選擇性寫入特定列等
    2024-09-09
  • OpenCV實現(xiàn)相機校正

    OpenCV實現(xiàn)相機校正

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)相機校正,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • python 實現(xiàn)讓字典的value 成為列表

    python 實現(xiàn)讓字典的value 成為列表

    今天小編就為大家分享一篇python 實現(xiàn)讓字典的value 成為列表,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python基礎(chǔ)請求庫urllib模塊使用深入探究

    Python基礎(chǔ)請求庫urllib模塊使用深入探究

    在Python中,urllib庫是一個強大的模塊,用于處理URLs,它包含了多個子模塊,其中urllib.request是用于發(fā)出HTTP請求的核心組件,本文將深入探討urllib的基本使用、高級功能以及一些實際場景的示例,方便更全面地了解這個重要的網(wǎng)絡(luò)請求工具
    2024-01-01
  • python順序的讀取文件夾下名稱有序的文件方法

    python順序的讀取文件夾下名稱有序的文件方法

    今天小編就為大家分享一篇python順序的讀取文件夾下名稱有序的文件方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • python 如何實現(xiàn)遺傳算法

    python 如何實現(xiàn)遺傳算法

    這篇文章主要介紹了python 如何實現(xiàn)遺傳算法,幫助大家更好的利用python進行數(shù)據(jù)分析、處理,感興趣的朋友可以了解下
    2020-09-09
  • Django異步任務(wù)之Celery的基本使用

    Django異步任務(wù)之Celery的基本使用

    這篇文章主要給大家介紹了關(guān)于Django異步任務(wù)之Celery使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Django具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • python中sys.argv參數(shù)用法實例分析

    python中sys.argv參數(shù)用法實例分析

    這篇文章主要介紹了python中sys.argv參數(shù)用法,實例分析了python中sys.argv參數(shù)的功能、定義及使用技巧,需要的朋友可以參考下
    2015-05-05

最新評論