Python靜態方法,其實暗藏玄機
文章首發於 微信公眾號:Python程式設計時光
這個標題「靜態方法其實暗藏玄機」其實只是該文章的一個知識點。或許有些標題黨,但沒有關係,我相信有不少人對此並沒有深入研究他們,不信我問你三個問題,你看能否答上來。
1、Python2.x和3.x中,函式和方法的區分有什麼不同?
2、有了類/例項方法和普通函式,為什麼還會有靜態方法?
3、Python3.x 中,靜態方法有幾種寫法?
帶著這三個問題,你可以嘗試在下文中尋找答案。
在 Python 2 中的函式和方法的區別,十分清晰,很好分辨。但在 Python3中,我卻發現完全又是另一套準則。
首先先來 Python2 的(以下在 Python2.7中測試通過)
可以得出結論:
1、普通函式(未定位在類裡),都是函式。
2、靜態方法(@staticmethod),都是函式。
3、類方法(@classmethod),都是方法。
4、例項方法(首引數為self且非靜態、非類方法的),都是方法。
你一定想說,類方法和例項方法,是方法沒錯呀,畢竟名字本身就有方法,普通函式是函式,我也理解呀。那靜態方法,為什麼不是方法而是函式呢?
名字只是一個外在的表面稱呼,你能說「趙鐵男」就一定是漢子嗎?
我的理解是:方法是一種和物件(例項或者類)繫結後的函式。
類方法的首參是cls
,呼叫時,無需顯示傳入。例項方法首參是self,呼叫時,也無需顯示傳入。
而靜態方法,其實和普通函式沒啥區別,唯一的區別就是,他定義的位置被放在了類裡,做為類或者例項的一個函式。
那你肯定又要問了,既然靜態方法和普通函式都是一樣的,為什麼要刻意將它放在類裡呢?
我上面說了,放在類裡定義,就可以讓它成為類的一個工具函式,這就像你身上隨身攜帶了一把刀,這把刀與你本人並沒有什麼直接關係,唯一的聯絡就是這把刀是你的,而你把它帶在身上,無論你去到哪裡,只要需要,你就可以直接拿出來用上。對比將函式放在類外面,缺點是什麼呢?就是當你出門在外(在別的模組裡)發現你要用刀的時候,還要特地跑一趟去商店買一把刀(import 這個函式)。
另外,我覺得靜態方法在業務和設計上的意義,會更多一些。
一般靜態方法是做為類或者例項的一個工具函式,比如對變數的做一個合法性的檢驗,對資料進行序列化反序列化操作等等。
說完了 Python2 ,再來說說Python3.
以前我覺得 Python2 對於方法和函式的界線更加清晰,但接觸了 Python3,我反而覺得Python3裡方法和函式的區分似乎更加合理。
還是剛剛那段程式碼,我更改了直譯器為Python3.6(以下在 Python3.6中測試通過)
和Python2的唯一區別是,People.jump
在Python3 中變成了函式。
這一下顛覆了你剛剛才建立起來的知識體系有木有?
先別急,我再做個試驗,也許你就知道了。
在 Python2中
執行People.jump('hello'),會報錯說,jump的首參必須為People的例項物件,這可以理解,畢竟jump定義時,第一個引數為self。
在 Python3中
你可以發現,這裡的jump的首參不再要求是 People 的一個例項,而可以是任意的物件,比如我使用字串物件,也沒有報錯。
也就是說,當你往jump中傳入的首參為People的例項時,jump 就是方法,而當你傳入的首參不是People的例項物件時,jump就是函式。
你看,多麼靈活呀。
再總結一下,在Python3中:
1、普通函式(未定位在類裡),都是函式。
2、靜態方法(@staticmethod),都是函式。
3、類方法(@classmethod),都是方法。
4、方法和函式區分沒有那麼明確,而是更加靈活了,一個函式有可能是方法也有可能是函式。
你肯定又要問了,那這是不是就意味著,Python3 中靜態方法,可以不用再使用@staticmethod 裝飾了呢,反正Python3都可以識別。
這是個好問題,是的,可以不用指定,但是最好指定,如果你不指定,你呼叫這個方法只能通過People.jump,而不能通過 self.jump了,因為首參不是 self,而如果使用@staticmethod 就可以使用self.jump。
所以說這是一個規範,就像類的私有方法,規範要求外部最好不要呼叫,但這不是強制要求,不是說外部就不能呼叫。
寫這篇文章的起源,是前兩天有位讀者在交流裡問到了相關的問題,正好沒什麼主題可以寫,就拿過來做為素材整理一下,也正好沒有寫過靜態方法、類方法的內容,沒想到簡單的東西,也能寫出這麼多的內容出來。
相關推薦
Python靜態方法,其實暗藏玄機
文章首發於 微信公眾號:Python程式設計時光 這個標題「靜態方法其實暗藏玄機」其實只是該文章的一個知識點。或許有些標題黨,但沒有關係,我相信有不少人對此並沒有深入研究他們,不信我問你三個問題,你看能否答上來。 1、Python2.x和3.x中,函式和方法的區分有什麼不同? 2、有了類/例項方法和普通函
python靜態屬性,靜態方法,類方法
類的屬性 tool 方法 method nbsp 靜態屬性 world assm 函數調用 #靜態屬性的作用是吧類的方法隱藏起來(可以把背後的邏輯隱藏起來),讓用戶感覺是在電泳屬性,而不是方法 class Static: attribute='屬性'
Python:類屬性,實例屬性,私有屬性與靜態方法,類方法,實例方法
所有 參數 方法 rate self 類屬性 不能 anaconda 賦值 類屬性可以直接在方法中賦值,但 一、調用該屬性時,必須先調用該方法; 二、與 init 方法區別是,init方法只初始化一次,初始化完成後作為全局變量。在方法中賦值屬性,每次調用該方法,該屬性初始化
少說話多寫程式碼之Python學習050——類的成員(靜態方法,類成員方法,getattr,setattr)
我們在訪問類的欄位時,還有一些過濾的條件,類似於前端語言比如vue Js、anjularJs中過濾器的概念。在3.0以前可以使用比如,__setattr__,__getattr__的方法進行屬性的過濾。在3.0以後我們如果對某些欄位需要過濾訪問,也可以使用這些函式。 class Rectan
Python-類變數,成員變數,靜態變數,類方法,靜態方法,例項方法,普通函式
#coding:utf-8 class class_name(object): class_var = 'I am a class variable' #類變數 def __init__(self): self.instance_
python 類和物件 (類屬性,類方法,靜態方法,例項屬性,例項方法)
類:類是抽象的,在使用的時候通常會找到這個類的一個具體的存在,使用這個具體的存在。一個類可以找到多個物件物件: 某一個具體事物的存在,在現實世界中可以是看的到摸得著的。 可以直接使用類與物件的關係: 類就是建立物件的模板類的構成: 1.類的名稱:
Python:類屬性,例項屬性,私有屬性與靜態方法,類方法,例項方法
1、定義一個類:1.1、類物件支援兩種操作:引用和例項化1.2、Python中屬性、方法和函式的區別:1.2.1、私有屬性:1.3、類屬性、例項屬性、類方法和例項方法:1.3.1、類方法1.3.2、例項方法1.3.3、靜態方法2、繼承1、定義一個類: class className: block bl
Python:類屬性,例項屬性,私有屬性與靜態方法,類方法,例項方法 屬性分為例項屬性與類屬性 方法分為普通方法,類方法,靜態方法 一:屬性: 儘量把需要使用者傳入的屬性作為例項屬性,而
屬性分為例項屬性與類屬性 方法分為普通方法,類方法,靜態方法 一:屬性: 儘量把需要使用者傳入的屬性作為例項屬性,而把同類都一樣的屬性作為類屬性。例項屬性在每創造一個例項時都會初始化一遍,不同的例項的例項屬性可能不同,不同例項的類屬性都相同。從而減少記憶體。 1:例項屬性: 最
python類方法,例項方法,靜態方法的區別
class MyClass: def method(self): print("method") @staticmethod def
python 類的例項方法,靜態方法,類方法辨析和例項講解
我們知道在python的類裡面可以定義三種類型的方法: class A(object): # 例項方法 def foo(self,x): print "executing foo(%s,%s)"%(self,x) #
python 面向對象 類方法,靜態方法,property
() spa 邏輯 prop def pri __init__ icm second property 內置裝飾器函數 只在面向對象使用 把方法當初屬性使用(方法不加參數) 例子: class Rectangle: def __init__(self,long
靜態方法,類方法,屬性方法
ack posit elf none pre name n) nal last 1.靜態方法:只是名義上歸類管理,實際上在靜態方法裏訪問不了類或實例中的任何屬性。相當於類的工具包。 class Dog(object): def __init__(self,name
synchronized修飾普通方法,修飾靜態方法,修飾代碼塊,修飾線程run方法 比較
共享數據 比較 art text run best 初始 一個 lol synchronized用於多線程設計,有了synchronized關鍵字,多線程程序的運行結果將變得可以控制。synchronized關鍵字用於保護共享數據。 synchronized實現同步的機制:
python3學習筆記 靜態方法,類方法,屬性方法
SM clas ssm inf pytho ID 靜態方法 delet 分享 靜態方法@statitmetod 只是名義上歸類管理,實際上在靜態方法裏訪問不了類或實例中的任何屬性 類方法@classmethed 只能訪問類變量,不能訪問實例變量 屬性方法@prope
python 普通方法,@classmethod,@staticmethod
turn 通過 source val get AR java 靜態方法 error 普通方法 實例化一個類,然後通過類的實例化去調用方法: class method1: def __init__(self): self.items = [1,2,3,] def g
java中靜態變數,靜態程式碼塊,靜態方法,例項變數,匿名程式碼塊的載入順序
1. java中靜態變數,靜態程式碼塊,靜態方法,例項變數,匿名程式碼塊 在Java中,使用{}括起來的程式碼稱為程式碼塊,程式碼塊可以分為以下四種: (1)普通程式碼塊:就是類中方法的方法體 public void xxx(){ //code }
靜態方法,類方法,屬性,setter用法,delete用法和屬性方法的應用場景
一、靜態方法 1.1、定義 在類中的方法前面通過@staticmethod裝飾器即可把其裝飾的方法變為一個靜態方法 1 2 3 4 5 6 7 8 9 10 class Person(object): &
淺析java中靜態方法,非靜態方法和構造方法的執行順序問題
https://blog.csdn.net/qq_42401622/article/details/81190406 對於java中的靜態方法,非靜態方法和構造方法的理解: 靜態方法是隨著的java中虛擬機器的類的載入而載入,是跟隨繫結在一起的。 public class Main{ s
Python 中的 @staticmethod和@classmethod(關鍵詞:Python/靜態方法/類方法/@staticmethod/@classmethod)
結合書籍,我的理解 靜態方法: 出現在類中,第 1 個引數不是例項、也不是類, 由 @staticmethod 裝飾的方法; 類方法: 出現在類中,第 1 個引數不是例項、而是類, 由 @classmethod 裝飾的方法。 class C: @staticmetho
java中靜態變數,靜態方法,靜態程式碼塊,構造程式碼塊,構造方法...執行順序
public class TestExeOrder { public TestExeOrder(){ System.out.println("類的構造方法執行了..."); } { System.out.println("構造程式碼塊執行了