1. 程式人生 > >python裝飾函式classmethod與staticmethod

python裝飾函式classmethod與staticmethod

classmethod與staticmethod

classmethod、staticmethod是分別指定函式為動態方法還是靜態方法,先看下面這個例子:

class Person:

    def __init__(self, name):
        self.name = name

    @classmethod
    def work(cls, name):
        return "%s is working!!!" % name

    @staticmethod
    def eat(name):
        return "%s is eating!!!" % name

    def sleep(self):
        return "%s is eating!!!" % self.name

print(Person.work)
print(Person.eat)
print(Person.sleep)

列印結果為:

<bound method Person.work of <class '__main__.Person'>>
<function Person.eat at 0x00000000025DAA60>
<function Person.sleep at 0x00000000025DAAE8>

可以看到@classmethod的函式是繫結的method而不是function,那麼method和function有什麼區別呢,先看下說明:

function —— A series of statements which returns some value toa caller. It can also be passed zero or more arguments which may beused in the execution of the body.
method —— A function which is defined inside a class body. Ifcalled as an attribute of an instance of that class, the methodwill get the instance object as its first argument (which isusually called self).

也就是說method是繫結在類裡面的方法,再看下面這組對比示例:

def work(name):
    return "%s is eating!!!" % name

class Person:

    def __init__(self, name):
        self.name = name

    def sleep(self):
        return "%s is eating!!!" % self.name

print(work)
print(Person.sleep)

person = Person("xiaoming")
print(person.sleep)

列印結果為:

<function work at 0x00000000029FA620>
<function Person.sleep at 0x00000000029FAA60>
<bound method Person.sleep of <__main__.Person object at 0x00000000023FA860>>

可以看到,在我們例項化類過後,函式會變成這種bound method,即繫結例項的方法。

當然,@classmethod常常是用來設定類,比如舉一個例子:

class Person:

    def __init__(self, name):
        self.name = name

    @classmethod
    def work(cls):
        cls.__init__(cls, "小明代工")
        print("%s is working!!!" % cls.name)

    def work_pub(self):
        print("%s is working!!!" % self.name)

xiaohong = Person("小紅")
xiaohong.work()
xiaohong.work_pub()

列印結果為:

小明代工 is working!!!
小紅 is working!!!

如果函式中沒有包含例項必須的變數時可以使用staticmethod,無需傳入例項,也不能傳入。

class Person:

    def __init__(self, name):
        self.name = name

    @staticmethod
    def work(name):  # 不能傳入self,所以整個函式內部也不會有self
        print("%s is working!!!" % name)
        
Person.work("xiaoming")
# 這裡列印結果為 xiaoming is working!!!

這樣做的好處就是不用例項化,可以外部直接呼叫work函式。