天天看點

Python @classmethod

@classmethod:

定義操作類,而不是操作執行個體的方法。classmethod改變了調用方法的方式,是以類方法的第一個參數是類本身,而不是執行個體。@classmethod最常見的用途是定義備選構造方法。

1.定義方式

Python中3種方式定義類方法, 正常方式, @classmethod修飾方式, @staticmethod修飾方式
  • 普通的self類方法foo()需要通過self參數隐式的傳遞目前類對象的執行個體;
  • @classmethod修飾的方法class_foo()需要通過cls參數傳遞目前類對象;
  • @staticmethod修飾的方法定義與普通函數是一樣的。

self和cls的差別不是強制的,隻是PEP8中一種程式設計風格,self通常用作執行個體方法的第一參數,cls通常用作類方法的第一參數。即通常用self來傳遞目前類對象的執行個體,cls傳遞目前類對象。

2. @classmethod 特點

  • 聲明一個類方法
  • 第一個參數必須是

    cls

    , 它可以通路類的屬性
  • 類的方法隻能通路類的屬性,不能通路執行個體屬性
  • 類的方法可以通過

    ClassName.MethodName()

    通路也可以通過執行個體來通路。
  • 它可以傳回一個類的執行個體

例子:

class Student:
    name = 'unknown' # class attribute
    def __init__(self):
        self.age = 20  # instance attribute

    @classmethod
    def tostring(cls):
        print('Student Class Attributes: name=',cls.name)
           

類方法通路執行個體屬性時,會報錯

class Student:
    name = 'unknown' # class attribute
    def __init__(self):
        self.age = 20  # instance attribute

    @classmethod
    def tostring(cls):
        print('Student Class Attributes: name=',cls.name,', age=', cls.age)
           
>>> Student.tostring()
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    Student.tostring()
  File "<pyshell#21>", line 7, in display
    print('Student Class Attributes: name=',cls.name,', age=', cls.age)
AttributeError: type object 'Student' has no attribute 'age'
           
from datetime import date

# random Person
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @staticmethod
    def fromFathersAge(name, fatherAge, fatherPersonAgeDiff):
        return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)

    @classmethod
    def fromBirthYear(cls, name, birthYear):
        return cls(name, date.today().year - birthYear)

    def display(self):
        print(self.name + "'s age is: " + str(self.age))

class Man(Person):
    sex = 'Male'

man = Man.fromBirthYear('John', 1985)
print(isinstance(man, Man))

man1 = Man.fromFathersAge('John', 1965, 20)
print(isinstance(man1, Man))
           

3. @classmethod 和 @staticmethod

@classmethod @staticmethod
聲明一個類的方法 聲明一個靜态方法
可以通路類的屬性,不可以通路執行個體屬性 既不可以通路類屬性,也不可以通路執行個體屬性
可以使用

ClassName.MethodName()

調用或者

object.MethodName()

.調用

ClassName.MethodName()

調用後者

object.MethodName()

可以聲明一個類的工廠方法,傳回一個執行個體 不可以傳回一個執行個體

不要小瞧女程式員