1. 程式人生 > >Python靜態方法,其實暗藏玄機

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——類的成員(靜態方法類成員方法getattrsetattr)

我們在訪問類的欄位時,還有一些過濾的條件,類似於前端語言比如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("構造程式碼塊執行了