日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python的@classmethod和@staticmethod

發布時間:2023/12/18 python 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python的@classmethod和@staticmethod 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文是對StackOverflow上的一篇高贊回答的不完全翻譯,原文鏈接:meaning-of-classmethod-and-staticmethod-for-beginner

Python面向對象編程中,類中定義的方法可以是@classmethod 裝飾的類方法,也可以是@staticmethod 裝飾的靜態方法,用的最多的還是不帶裝飾器的實例方法。為方便,在下文中用@classmethod裝飾的類方法將直接用@classmethod來表述,@staticmethod同理,望讀者在閱讀時自行加以區分。

@classmethod和@staticmethod很相似,它們裝飾的方法在使用上只有一點區別:@classmethod裝飾的方法第一個參數必須是一個類(通常為cls),而@staticmethod裝飾的方法則按業務需求設置參數,也可以根本沒有參數。

?

樣例

樣例是一個處理日期信息的類,如下:

  • class Date(object):
  • def __init__(self, day=0, month=0, year=0):
  • self.day = day
  • self.month = month
  • self.year = year
  • 這個類可以用來存儲指定日期(不包括時區信息,假設所有日期都是UTC時間)。

    ??????? 這個類有一個__init__函數用來初始化實例對象,它的第一個必須的參數self指向一個已創建的Date類的實例對象,這個方法是一個典型的實例方法。

    ?

    Class Method

    ?

    有些任務用@classmethod 可以很好地完成。

    假設我們要從一堆有著特定日期格式的字符串(如'dd-mm-yyyy')創建很多對應的Date類的實例,而且在項目的各個地方都要進行這樣的轉換。那么我們要做的是:

    1. 解析一個字符串來得到day,month,year這三個整數變量或者組裝出一個tuple

    2. 把這些值傳遞給初始化函數來實例化Date實例對象

    比如:

  • day, month, year = map(int, string_date.split('-'))
  • date1 = Date(day, month, year)
  • ?

    要實現這個目的,C++可以使用重載,但是Python沒有這樣的語法,但是可以使用@classmethod來實現,如下:

  • @classmethod
  • def from_string(cls, date_as_string):
  • day, month, year = map(int, date_as_string.split('-'))
  • date1 = cls(day, month, year)
  • return date1
  • date2 = Date.from_string('11-09-2012')
  • 仔細比較這兩種方法,使用@classmethod有以下優點:

    1. 我們只寫了一個轉換字符串的方法,而且這個方法是可重用的。

    2. 把這個方法封裝在類中,更緊密(也許你會認為可以寫一個單獨的函數去轉換字符串,但是使用@classmethod更符合面向對象的思維)。

    3. cls 是類本身的對象,而不是類的實例對象,這樣的話繼承自Date的對象都會有from_string這個方法。

    ?

    Static Method

    那么@staticmethod呢?其實它跟@classmethod非常相似,只是它沒有任何必需的參數。

    假設我們要去檢驗一個日期的字符串是否有效。這個任務與Date類相關,但是又不需要Date實例對象,在這樣的情況下@staticmethod就可以派上用場了。如下:

  • @staticmethod
  • def is_date_valid(date_as_string):
  • day, month, year = map(int, date_as_string.split('-'))
  • return day <= 31 and month <= 12 and year <= 3999
  • # usage:
  • is_date = Date.is_date_valid('11-09-2012')
  • 從上面的用法可以看出,它只是一個功能,調用的語法和一般的方法調用一樣,也不訪問實例對象那和它的內部字段和方法。

    ?

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    以下有錯誤的地方

    ?

    類的普通方法

    class Animal(object):def __init__(self,name): self.name = name def intro(self): print('there is a %s'%(self.name)) cat = Animal('cat') cat.intro()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    靜態類方法

    class Animal(object):def __init__(self,name): self.name = name @staticmethod def intro(self): print('there is a %s'%(self.name)) cat = Animal('cat') cat.intro()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    加上裝飾器后運行會報錯,原因是方法變為一個普通函數,脫離的與類的關系,不能引用構造函數中的變量了。

    使用場景舉例:python內置方法os中的方法,可以直接使用的工具包,跟類沒關系。


    class Animal(object):def __init__(self,name): self.name = name @classmethod def intro(self): print('there is a %s'%(self.name)) cat = Animal('cat') cat.intro()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    報錯信息

    如果換成

    class Animal(object):name = 'cat' def __init__(self,name): self.name = name @classmethod def intro(self): print('there is a %s'%(self.name)) cat = Animal('cat') cat.intro()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    可以正常運行。
    結論:類方法只能調用類變量,不能調用實例變量


    屬性方法@property 把一個方法變為(偽裝成)類屬性。因為類屬性的實質是一個類變量,用戶可以調用變量就可以修改變量。某些特定場景要限制用戶行為,就用到靜態方法。
    @property廣泛應用在類的定義中,可以讓調用者寫出簡短的代碼,同時保證對參數進行必要的檢查,這樣,程序運行時就減少了出錯的可能性。(摘自廖雪峰的博客)

    class Animal(object):def __init__(self,name): self.name = name @property def intro(self,food): print('there is a %s eating %s'%(self.name,food)) cat = Animal('cat') cat.intro()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    報錯:
    方法不能正常調用。如果要調用,如下:

    cat.intro
    • 1

    但是這樣的話,方法就沒辦法單獨傳入參數。如果要傳入參數,如下:

    class Animal(object):def __init__(self,name): self.name = name @property def intro(self): print('there is a %s eating %s'%(self.name,food)) @intro.setter def intro(self,food): pass cat = Animal('cat') cat.intro
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    cat.intro還有其他操作getter deleter等等。

    ?

    轉載于:https://www.cnblogs.com/fengff/p/9587952.html

    總結

    以上是生活随笔為你收集整理的python的@classmethod和@staticmethod的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。