自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在什么情況下使用@property比較好?

開發(fā) 后端
對于習(xí)慣于 Java 的人來說,他們可能喜歡顯式寫出get_xxx和set_xxx方法。但是對于習(xí)慣 Python 的人來說,我覺得使用@property會讓代碼的可讀性更好。

我在2016年的時候,寫過一篇文章,介紹@property裝飾器。4年過去了,本來以為這個裝飾器使用起來應(yīng)該是很自然的事情,但還是有同學(xué)不知道在什么場景下可以使用它。

[[352810]]

他們是這樣說的:

  1. class People: 
  2.     def __init__(self, name): 
  3.         self.name = name 
  4.         self._work = '還沒有找到工作' 
  5.  
  6.     @property 
  7.     def work(self): 
  8.         return self._work 
  9.  
  10.     @work.setter 
  11.     def work(self, value): 
  12.         self._work = value 

運行效果如下圖所示:

但實際上,這段代碼里面,@property裝飾器根本沒有任何存在的必要,代碼完全可以進(jìn)一步簡化:

  1. class People: 
  2.     def __init__(self, name): 
  3.         self.name = name 
  4.         self.work = '還沒有找到工作' 

運行結(jié)果完全一樣:

那么,使用@property裝飾器的意義在哪里呢?

的確,在上面的例子里,@property裝飾器沒有任何存在的必要,因為這里讀取一個對象的屬性,僅僅是“返回數(shù)據(jù)”而已。但有些情況下,不僅僅要讀取,還要計算。

我舉一個例子,不知道你有沒有這樣的經(jīng)歷,你剛剛看了一眼手機,發(fā)現(xiàn)現(xiàn)在時間是23:10分。30秒以后,你朋友碰巧問你多少點了,你立刻回答:23:10分。他一看手表,還真是。于是驚呼,你怎么不看表就知道時間?

例如我們現(xiàn)在要實現(xiàn)一個ProxyProvider類,它讀取 Redis,獲取最新的代理 IP,然后隨機返回一條。另外有一個程序,會增加新的代理 IP 到 Redis 中。但頻率不高。

所以,ProxyProvider這個類,不需要每次獲取 IP 的時候都讀取數(shù)據(jù)庫,每小時讀取一次就可以了。如果不用@property裝飾器,你可能會這樣寫代碼:

  1. import time 
  2. import random 
  3.  
  4.  
  5. class ProxyProvider: 
  6.     def __init__(self): 
  7.         self.pool = [] 
  8.         self.last_update_time = 0 
  9.  
  10.     def get_proxy(self): 
  11.         now = time.time() 
  12.         if now - self.last_update_time > 3600 or not self.pool: 
  13.             selfself.pool = self.get_all_proxies_from_redis() 
  14.         return random.choice(self.pool) 

如果你經(jīng)???Java 代碼,你會發(fā)現(xiàn)大量的這種get_xxx、set_xxx的寫法。

于是,調(diào)用的時候,要這樣調(diào)用:

  1. provider = ProxyProvider() 
  2. provider.get_proxy() 

如果用@property,那么代碼可以改寫為:

  1. import time 
  2. import random 
  3.  
  4.  
  5. class ProxyProvider: 
  6.     def __init__(self): 
  7.         self.pool = [] 
  8.         self.last_update_time = 0 
  9.  
  10.     @property 
  11.     def proxy(self): 
  12.         now = time.time() 
  13.         if now - self.last_update_time > 3600 or not self.pool: 
  14.             selfself.pool = self.get_all_proxies_from_redis() 
  15.         return random.choice(self.pool) 

于是讀取的時候,這樣寫:

  1. provider = ProxyProvider() 
  2. provider.proxy  # 注意這里不加括號 

我們可以看到,整體代碼邏輯是一樣的,代碼里并沒有精簡。不過在調(diào)用的時候,前者是調(diào)用一個方法,后者是讀取一個屬性。

同理,如果要修改數(shù)據(jù),不使用@property的時候,需要實現(xiàn)一個set_xxx方法。但是使用了@property裝飾一個方法,也可以在設(shè)置數(shù)據(jù)的時候?qū)崿F(xiàn)一些內(nèi)部邏輯,例如:

  1. import time 
  2. import random 
  3.  
  4.  
  5. class ProxyProvider: 
  6.     def __init__(self): 
  7.         self.pool = [] 
  8.         self.special_ip = set() 
  9.         self.last_update_time = 0 
  10.  
  11.     @property 
  12.     def proxy(self): 
  13.         now = time.time() 
  14.         if now - self.last_update_time > 3600 or not self.pool: 
  15.             selfself.pool = self.get_all_proxies_from_redis() 
  16.         return random.choice(self.pool + list(self.special)) 
  17.  
  18.     @proxy.setter 
  19.     def proxy(self, value): 
  20.         if not value.startswith('http'): 
  21.             proxy = f'http://{ip}' 
  22.         if proxy in self.special_ip: 
  23.             return 
  24.         self.special_ip.add(proxy) 

而對于調(diào)用者來說,這些復(fù)雜的檢查邏輯都是透明的:

  1. provider = ProxyProvider() 
  2. provider.proxy = '123.45.67.89' 

對于習(xí)慣于 Java 的人來說,他們可能喜歡顯式寫出get_xxx和set_xxx方法。但是對于習(xí)慣 Python 的人來說,我覺得使用@property會讓代碼的可讀性更好。

 

責(zé)任編輯:趙寧寧 來源: 未聞Code
相關(guān)推薦

2013-07-29 14:50:43

API

2015-06-01 06:39:18

JavaJava比C++

2015-06-29 14:23:13

JavaC++慢很多

2023-11-23 23:52:06

options請求瀏覽器

2014-11-03 09:52:25

DNSUDPTCP

2024-01-09 11:39:47

數(shù)字化轉(zhuǎn)型數(shù)字優(yōu)先企業(yè)

2013-09-12 10:41:39

VDI部署

2021-06-04 09:17:13

JavaScriptBoolean函數(shù)

2010-07-20 12:46:23

SQL Server聚

2022-07-20 08:07:21

數(shù)據(jù)庫分布式數(shù)據(jù)庫

2013-09-23 10:05:50

2010-07-13 16:07:26

SQL Server行

2023-05-18 08:38:13

Java鎖機制

2009-03-05 10:55:00

企業(yè)無線Wi-Fi

2021-09-14 07:26:25

雪花算法ID

2010-04-14 17:46:10

Oracle數(shù)據(jù)庫

2024-11-07 12:08:27

微服務(wù)協(xié)議通信

2009-09-15 09:24:42

思科認(rèn)證考試思科認(rèn)證

2020-09-24 09:43:59

Http協(xié)議options請求

2012-04-25 09:24:40

Android
點贊
收藏

51CTO技術(shù)棧公眾號