Python中的靜態方法、類方法以及對象方法(實例方法)

2021-02-20 IT職場課堂

自己喜歡,

就好。


通過一個例子來區分三者的區別和使用場景:

定義一個Date類來輸出日期:

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

再在類中重新定義它的__str__方法,這樣在列印的時候就可以直接列印出日期:

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

運行一下:

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

if __name__ == "__main__":
new_day = Date(2018,12,30)
print(new_day)

運行結果:

在上面的代碼中__init__和__str__都是實例方法也就是對象方法。
再定義一個實例方法:

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def tomorrow(self):
self.day += 1

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

if __name__ == "__main__":
new_day = Date(2018,12,30)
new_day.tomorrow()
print(new_day)

運行結果:

在上面的代碼中,傳遞給Date的值是2018、12、30三個數字,如果希望傳遞進來的是一個日期的字符串,如「2018-12-30」。
首先想到的方法就是split分割字符串,然後把對應的值賦給變量。
先在類外實現這個功能:

date_str = "2018-12-30"

year, month, day = tuple(date_str.split("-"))
print(year, month, day)
print(type(year))

運行結果:

image.png

這時候year、month、day的值的類型都是字符串,所以賦值的時候要進行類型轉換:

date_str = "2018-12-30"

year, month, day = tuple(date_str.split("-"))
print(year, month, day)
print(type(year))
new_day = Date(int(year), int(month), int(day))
print(new_day)

運行結果:

image.png


也就是說,每一次實例化的時候,都要運行上面的分割字符串,並把值賦給對應的變量這段代碼,所以就可以在類中定義一個靜態方法,也就是在def的上一行加上@staticmethod這句

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def tomorrow(self):
self.day += 1

@staticmethod
def parse_from_string(data_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

這個靜態方法接收不需要self,也不需要接收class對象,與普通的函數用法相同。

  new_day = Date.parse_from_string(date_str)

print(new_day)

運行一下:

image.png

這個靜態方法實現起來更簡單,也更易懂,缺點是,硬編碼。(return硬編碼,把Date直接返回了,也就是如果一旦改變了類名,這個位置也必須要修改),要想解決這個問題可以使用類方法。

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def tomorrow(self):
self.day += 1

@staticmethod
def parse_from_string(data_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))

@classmethod
def from_string(cls,date_str):
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day))

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

類方法和實例方法的區別是:
類方法首先傳遞進來的是類,也就是cls,它是class的簡寫,cls改成self也是不會有問題的。

既然這樣類方法就完全可以取代靜態方法了嗎。

如果想要判斷傳遞進來的字符串是否是合法的時間,那麼就沒有必要把類傳遞到方法中,這時候使用靜態方法更方便一些。

class Date:

# 構造函數
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def tomorrow(self):
self.day += 1

@staticmethod
def parse_from_string(data_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))

@staticmethod
def valid_str(data_str):
year, month, day = tuple(date_str.split("-"))
if int(year) > 0 and int(month) > 0 and int(month) < 13 and int(day) > 0 and int(day) < 32:
return True
else:
return False

@classmethod
def from_string(cls,date_str):
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day))

def __str__(self):
return "{year}/{month}/{day}".format(year = self.year, month = self.month,day = self.day)

這裡只是簡單實現了一下判斷,實際在判斷字符串是否是合法的時間比這要複雜得多。

       new_day = Date.from_string(date_str)

print(new_day)
print(new_day.valid_str(date_str))

運行一下:



作者:李白開水
來源:簡書

相關焦點

  • Python每天一分鐘:實例方法、靜態方法、類方法詳解(附代碼)
    在面向對象的編程中,已知類屬性可細分為類屬性和實例屬性一樣,同樣的,對於類中的方法也可以具體可劃分為類方法、實例方法和靜態方法!本文將通過代碼演示對這三種方法做將詳細介紹!python類編程三大方法Python實例方法在類編程中,一般情況下在類中定義的方法/函數默認都是實例方法。我們以下圖中的代碼來詳細說明:
  • Python入門基礎之面向對象二:類和實例、方法
    前面一篇文章我介紹了python面向對象的基本知識,連結在最下面。初步解釋了面向對象和面向對象的優點,今天就開始正式用代碼來展現面向對象。1、利用class創建類Python中,創建類的語句是如下所示先解釋一下,class後面跟的是類名,括號裡面是基類(也成為父類)python3中默認繼承object。
  • Python中你不知道的事:多繼承和類的方法,以及什麼是類的特殊方法
    可以同時繼承多個父類Python中可以有兩個以上的父類,當有A,B,C三個父類的時候,第三個父類可以同時繼承A與B兩類,C可以使用A與B中的屬性和方法。也就是說類屬性只能有類來刪除,實列屬性只能用 實列來刪除。如果實列修改了共有屬性(類屬性),那樣的結果就是說我們再刪除的時候是刪除的不是類中的元素,而是刪除的是自己修改的屬性,刪除之後指向的是共有屬性中的類屬性。類屬性只能用類名來刪除,實列屬性要用實例來刪除。isinstance實例
  • 詳解Python類中不同方法的應用
    主要是用來存放邏輯性的代碼,邏輯上屬於類,但是和類本身沒有關係,也就是說在靜態方法中,不會涉及到類中的屬性和方法的操作。可以理解為,靜態方法是個獨立的、單純的函數,它僅僅託管於某個類的名稱空間中,便於使用和維護。通常情況下,靜態方法使用@staticmethod裝飾器(或使用staticmethod())來聲明。
  • 黑馬程式設計師:Python封裝、繼承和多態以及類方法等習題
    習題總結:本文的習題繼續面向對象編程的知識點,包括面向對象的三大特徵,圍繞類屬性和實例屬性,還有類的方法和靜態方法。通過本章內容的學習複習,大家對面向對象應該會有比較深入的了解了。為以後的開發奠定好紮實的面向對象編程思想。如果有需要答案的小夥伴依舊是轉發後評論獲取。
  • Java開發中靜態方法引用和實例方法引用案例詳細講解
    當然Java8憋出方法引用這麼一個大招,絕非只想讓它走過場而已,而是要除舊革新深入應用。其實僅僅涉及到方法引用的其中一個分支——參數方法引用,該分支顧名思義被引用的方法對應於入參的數據類型。方法引用還有其它兩個分支,分別是靜態方法引用和實例方法引用,接下來依次進行詳細說明。  首先是靜態方法引用,所謂靜態表示被引用的方法乃某個工具類的靜態方法。
  • Java中的static關鍵字和靜態變量、靜態方法
    作者: Java進階者 來源:Java進階學習交流一、static關鍵字使用static修飾的變量和方法分別稱為類變量(或稱靜態變量)和類方法(或稱靜態方法),沒有使用static修飾的變量和方法分別稱為實例變量和實例方法
  • 《手把手陪您學Python》41——類方法與實例方法
    在上一篇《手把手陪您學Python》40——類的定義、屬性與實例化中,我們學習了面向對象編程的基礎知識,了解了類的屬性以及實例化屬性等,今天我們將會主要介紹類的方法以及實例方法
  • 面試官:為什麼java中靜態方法不能調用非靜態方法或變量?
    main中調用非靜態變量或者是方法都會報錯。我們反過來看看:反過來沒有一點問題,接下來我們解釋一下原因:二、原因解釋我們需要首先知道的是靜態方法和靜態變量是屬於某一個類,而不屬於類的對象。我們不直接講原因,先從jvm說起:這是一張類加載的生命周期圖。
  • Python新式類的方法解析順序MRO與Super
    python3以前新式類:廣度優先 python2.2新式類:廣度優先的C3算法實現(拓撲排序) BFS python2.3及以後python 用MRO的目的是什麼解決多重繼承的二義性的問題(二義性:父類存在同名函數的時候會產生二義性)為python調用一個類或者實例方法的時候提供查找順序
  • Python學習:類和實例
    其次,語言中類是抽象的模板,用來描述具有相同屬性和方法的對象的集合,比如Animal類。而實例是根據類創建出來的一個個具體的「對象」,每個對象都擁有相同的方法,但各自的數據可能不同。:Python的類中包含實例方法、靜態方法和類方法三種方法。
  • Python 中常用的魔術方法
    博客地址:zhihu.com/people/zarten概述python中特殊方法(魔術方法)是被python解釋器調用的,我們自己不需要調用它們,我們統一使用內置函數來使用。通過實現一個類來說明常用特殊方法及實現一般返回數量,使用len()方法調用。
  • Python 中的函數與方法 以及 Bound Method 和 Unbound Method
    隨著我們越來越頻繁使用Python, 我們難免會接觸到類, 接觸到類屬性和方法.但是很多新手包括我, 不知道方法 和 函數 的區別,這次簡單來討論下, 如果有哪裡認識不正確, 希望大神提點指教!        return 1a = A()print '#### 各自方法描述 ####'print '## 函數     %s' % aaprint '## 類方法   %s' % A.fprint '## 實例方法 %s' % a.f輸出結果:#### 各自方法描述 ####
  • 全面深入理解 Python 類與對象
    magic.name)返回結果:浪子浪子三大方法python類的調用有三大方法,分別是類方法,靜態方法,實例方法。這三個方法在曾經的文章有說過。Python面向對象編程這裡就不多做代碼重寫,去原連結查看學習即可。數據封裝與私有屬性私有屬性,也叫私有方法,是以雙下劃線開頭的命名變量。無法通過實例方法和子類來調用的,只能通過類中寫的方法來調用。
  • python 類(3) 私有屬性/方法
    慢慢努力吧內容提要類中的__變量python中,在類的定義中在變量名前加雙下劃線的變量,稱為類的私有屬性,其本意是不讓類的實例訪問變量class MyClass(object): def __init__(self): self.
  • Python生成器next方法和send方法區別詳解
    在python中有兩種方式創建生成器:生成淺談Python中的可迭代對象、迭代器、For循環工作機制、生成器1.iterable iterator區別 要了解兩者區別,先要了解一下迭代器協議: 迭代器協議是指:對象需要提供__next__()方法,它返回迭代中的元素,在沒有更多元素後,拋出StopIteration異常,終止迭代. 可迭代對象就是:實現了迭代器協議的對象.
  • python面向對象中的self,cls,staticmethod,classmethod
    這裡會說到:類方法,靜態方法,類屬性,實例方法等相關。一開始我並沒有get到這種做法有什麼特別妙的地方,看了眾多大佬的解讀,總結出:•減少實例化對象的開銷,如果方法沒有用到實例化的任何屬性和方法,推薦使用靜態類方法@staticmethod•屬於類的方法放到類裡面,利於組織代碼,容易閱讀。
  • 柳小白Python學習筆記 10 內置方法之列表方法
    python3.7幫助文檔中是這樣定義方法的:方法是使用屬性表示法來調用的函數。 存在兩種形式:內置方法和類實例方法。 內置方法由支持它們的類型來描述。前面學習數據類型的時候學習了許多方法,我看不懂英文幫助文檔,而查了好多資料都是說類實例方法的,說方法是定義在類中的函數。但是學習的時候感覺這些方法沒在類中定義呀,很疑惑。
  • 超詳細解讀Java接口:模塊通信協議以及默認方法和靜態方法
    前面已經介紹過,接口中的方法都是抽象的,某個類實現了接口,就要實現接口中的所有方法,如果沒有完全實現接口中的方法,那麼這個類就必須聲明為抽象類。desc,而Flyable接口也有一個同名的默認方法desc,Bird類同時實現了這兩個接口,如果Bird類的對象調用desc方法,那麼應該調用哪個接口中的desc方法呢?
  • Python中必須知道的5對魔術方法
    實例化: __new__ 和 __init__在學習了 Python 數據結構的基礎知識(例如字典,列表)之後,您應該已經看到了一些定義自定義類的示例,在這些示例中,您第一次接觸到了魔術方法 __init__。此方法用於定義實例對象的初始化行為。具體來說,在 __init__ 方法中,您想要為創建的實例對象設置初始屬性。