84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
这两个东西在什么情况下用
认证高级PHP讲师
簡單來說
@property 是 Python 中用來取代 getter/setter 的 decorator,他可以包裝、處理、封裝類屬性,也可以很方便地建立唯讀屬性,重點是他維持了 介面的簡單。因為我們能夠很直覺的存取屬性而不必使用冗贅地使用 get_XXX 和 set_XXX 這類的 getter/setter。我本來也想打一篇完整的說明,但是下筆思考後覺得不夠全面,所以還是先放棄待日後補齊,如果有其他高手很了解這一塊的,歡迎給發問者和小弟我一點意見。
@property
get_XXX
set_XXX
@staticmethod 我覺得是 沒什麼實際作用 非必要 的 decorator (這點如果大家有不同意見,歡迎討論,我滿想討論這個的)
@staticmethod
(這次的回答比較艱澀一點,如果覺得繁體看起來吃力,可以用 browser 轉成簡體後看...)
先講staticmethod 好了,被 staticmethod 修飾的 method 並不會接收特殊的第一項引數 (一般的 instance method 和被 classmethod 修飾過的類別方法 分別會接受實例和類別的參考作為第一項參數),這讓靜態方法就像是個一般的function,只是他剛好被定義在class 裡而不是直接定義在module level。
staticmethod
classmethod
所以他的 使用情境就是: 當某個類別裡面的函數不需要像是 self 或是 cls 等實例或類別的參考時,使用靜態方法可以比較簡潔且有效率地完成工作。
self
cls
簡明的部分在於不需要多接收一個無關緊要的引數
效率在於一般的實例方法是 bound method (是個 object) 且是在我們要使用他的時候才生成,這會花上多一點點的 cost,而靜態方法並不會
但我覺得他並不實用,首先與類別有直接關係的函數我們可以用 classmethod 就好,在代碼之中我們依靠第一項引數提供的 class 參考能夠完成與類有關的操作 (比如說 __init__ 的替代物 或是 做為一個調度更多子 staticmethod 的上層方法)。
__init__
若非與類別有關(而又與實例無關),那我們需要類別靜態方法的目的,我暫時只想的到一個: 為了呼叫上能夠有一個抽象的層級(沒錯,我說的就是namespace )而此函數雖然不會直接接觸類別但是卻與類別有關。
但是在Python 之中,使用namespace 是很容易的事情,我們不如將原先想要定義成靜態方法的函數定義在module 層級,且盡可能地放在有關類別的附近,我想就非常足夠了( Luciano Ramalho 的觀點)。
namespace
就在我打完上面這段之後,我特意看了一次Julien Danjou 的一篇超棒的文章:The definitive guide on how to use static, class or abstract methods in Python我強力推薦任何想弄清楚Python method 的人看這篇文章。
這篇文章提出了兩點 staticmethod 的優點,第一點我在上面已經有提到了,靜態方法比起實例方法來的簡明與有效率。第二點是靜態方法 雖然與類別無關但是屬於類別的 ,這代表他可以客制化地為類別服務。這有點難懂,我們看一個例子好了( Julien Danjou 文章中範例):
class Pizza(object): @staticmethod def mix_ingredients(x, y): return x + y def cook(self): return self.mix_ingredients(self.cheese, self.vegetables)
我們想像一下,如果我們把 mix_ingredients 定義在 module level,那當我們在處理繼承 Pizza 的子類時,勢必無法藉由改動 mix_ingredients 來更動 mix ingredients 的行為 (因為該函數有別的類在使用),那我們只好複寫 cook 了。
mix_ingredients
Pizza
cook
這個理由有一點點讓我改觀,起碼他指出了一個靜態方法跟一般方法的最大不同,靜態方法是單屬於某一類的。
不過我還是比較堅持原先的想法,因為也許 mix_ingredients 可以寫得更好,又或者是對於 Pizza 這種非抽象類別根本是不要去繼承他的,又或是繼承的時候複寫方法是不好的,甚至我可以覺得更動 mix_ingredients 跟更動 cook 同樣都是個負擔。
以上都是 我覺得,也許哪一天 staticmethod 讓我真正優雅地派上用場了,我可能會承認今天我愚昧而膚淺的認識吧。至於你呢? 我覺得你可以有自己的想法,只要你在了解夠多的情況下還能說服自己,那我覺得沒有任何立場是錯的 :)
我回答過的問題: Python-QA
簡單來說
@property
是 Python 中用來取代 getter/setter 的 decorator,他可以包裝、處理、封裝類屬性,也可以很方便地建立唯讀屬性,重點是他維持了 介面的簡單。因為我們能夠很直覺的存取屬性而不必使用冗贅地使用get_XXX
和set_XXX
這類的 getter/setter。我本來也想打一篇完整的說明,但是下筆思考後覺得不夠全面,所以還是先放棄待日後補齊,如果有其他高手很了解這一塊的,歡迎給發問者和小弟我一點意見。@staticmethod
我覺得是沒什麼實際作用非必要 的 decorator (這點如果大家有不同意見,歡迎討論,我滿想討論這個的)(這次的回答比較艱澀一點,如果覺得繁體看起來吃力,可以用 browser 轉成簡體後看...)
@staticmethod
特色與使用情境
先講
staticmethod
好了,被 staticmethod 修飾的 method 並不會接收特殊的第一項引數 (一般的 instance method 和被classmethod
修飾過的類別方法 分別會接受實例和類別的參考作為第一項參數),這讓靜態方法就像是個一般的function,只是他剛好被定義在class 裡而不是直接定義在module level。所以他的 使用情境就是: 當某個類別裡面的函數不需要像是
self
或是cls
等實例或類別的參考時,使用靜態方法可以比較簡潔且有效率地完成工作。簡明的部分在於不需要多接收一個無關緊要的引數
效率在於一般的實例方法是 bound method (是個 object) 且是在我們要使用他的時候才生成,這會花上多一點點的 cost,而靜態方法並不會
實用/不實用?
但我覺得他並不實用,首先與類別有直接關係的函數我們可以用
classmethod
就好,在代碼之中我們依靠第一項引數提供的 class 參考能夠完成與類有關的操作 (比如說__init__
的替代物 或是 做為一個調度更多子staticmethod
的上層方法)。若非與類別有關(而又與實例無關),那我們需要類別靜態方法的目的,我暫時只想的到一個: 為了呼叫上能夠有一個抽象的層級(沒錯,我說的就是namespace )而此函數雖然不會直接接觸類別但是卻與類別有關。
但是在Python 之中,使用
namespace
是很容易的事情,我們不如將原先想要定義成靜態方法的函數定義在module 層級,且盡可能地放在有關類別的附近,我想就非常足夠了( Luciano Ramalho 的觀點)。反思
就在我打完上面這段之後,我特意看了一次Julien Danjou 的一篇超棒的文章:
The definitive guide on how to use static, class or abstract methods in Python
我強力推薦任何想弄清楚Python method 的人看這篇文章。
這篇文章提出了兩點
staticmethod
的優點,第一點我在上面已經有提到了,靜態方法比起實例方法來的簡明與有效率。第二點是靜態方法 雖然與類別無關但是屬於類別的 ,這代表他可以客制化地為類別服務。這有點難懂,我們看一個例子好了( Julien Danjou 文章中範例):我們想像一下,如果我們把
mix_ingredients
定義在 module level,那當我們在處理繼承Pizza
的子類時,勢必無法藉由改動mix_ingredients
來更動 mix ingredients 的行為 (因為該函數有別的類在使用),那我們只好複寫cook
了。這個理由有一點點讓我改觀,起碼他指出了一個靜態方法跟一般方法的最大不同,靜態方法是單屬於某一類的。
不過我還是比較堅持原先的想法,因為也許
mix_ingredients
可以寫得更好,又或者是對於 Pizza 這種非抽象類別根本是不要去繼承他的,又或是繼承的時候複寫方法是不好的,甚至我可以覺得更動mix_ingredients
跟更動cook
同樣都是個負擔。小結
以上都是 我覺得,也許哪一天
staticmethod
讓我真正優雅地派上用場了,我可能會承認今天我愚昧而膚淺的認識吧。至於你呢? 我覺得你可以有自己的想法,只要你在了解夠多的情況下還能說服自己,那我覺得沒有任何立場是錯的 :)我回答過的問題: Python-QA