python裝飾函式classmethod與staticmethod
阿新 • • 發佈:2018-12-15
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函式。