Python进阶(六):@classmethod和@staicmethod

来源:互联网 发布:java webservice demo 编辑:程序博客网 时间:2024/05/16 14:25

有时我们会在python的代码里面看到这两个修饰器,用于修饰类的函数。也许有人会问这两个修饰器原理是怎么样的?或者说在什么场景下运用这两个修饰器呢?

一.预备知识:实例化

首先,python的类是一种动态化的编程。
也就是我们在平时定义一个类的后,想使用这个类的函数,我们必须先将一个类实例化。
比如下面我们定义了一个test类,然后实例化:

class test(object):    def __init__(self):        self.data = "This is a class"    def method(self):        return self.data#实例化t = test()

t = test()就是实例化的操作了
但是我们并不想实例化,然后就调用类中函数,会出现什么情况呢?我们执行下面的代码:

print(test.method())

就会报出以下错误:
这里写图片描述
主要是因为method这个函数需要传入一个参数,而这个参数就是这个类本身,而根据类定义,在没有实例化之前,这个类是不存在的,所以没有本身这一说。
那么,有什么办法比较好的解决呢?


二.@staictmethod:静态方法

上面的问题我们可以通过静态方法很好的解决。当使用@statictmethod修饰一个类函数的时候,就将这个函数静态化了,也就是可以在不用实例化的前提下调用这个函数了。
例子:

class test(object):    def __init__(self):        self.data = "This is a class"    @staticmethod    def method():        return test().dataprint(test.method())

结果:
这里写图片描述
平时我们就可以将一个静态的方法归并入类中,可以在不用实例化的前提下就调用这个函数,这样一来可以更方便了


三.@classmethod:类方法

除了静态方法,我们还有类方法。这个方法理解起来可能会有点绕。
所谓的类方法就是将类自身作为参数传回函数中作为参数。
看以下例子:

class test(object):    def __init__(self):        self.data = "This is a class"    @classmethod    def method(cls):        return cls.dataprint(test.method())

你以为这样就对的吗?
错,大错特错。
结果:
这里写图片描述
为什么会这样的,因为我们并没有实例化一个类,这样类的__init__(self)就没有被调用,也就是data并存在。
我们只需要改成这样就可以啦:

class test(object):    data = "this a class"    @classmethod    def method(cls):        return cls.dataprint(test.method())

结果:

E:\python3.6\python.exe F:/python项目/练习/ex1.pythis a class

下图帮助理解下classmethod的工作方式,就是将自身传递给函数做参数:
这里写图片描述
如果还有点迷糊,那就看代码吧:

class test(object):    data = "this a class"    @classmethod    def method(cls):        return clsprint(test.method())

结果:这里写图片描述


四.用处

说了这么多那么这两个方法具体可以用在什么地方呢?
学过c++的都知道c++有个构建方法就是重构,就是允许类有多种实例化的方法。也就是说在实例化过程中,可以允许传入不同的参数。而在python中是不允许的,可是静态方法还有类方法很好的帮我们解决了这个问题。
看下面这个例子:

class Date(object):    def __init__(self, month=0, day=0, year=0):        self.day = int(day)        self.month = int(month)        self.year = int(year)    @classmethod    def from_string(cls, date_string):        month, day, year = date_string.split('-')        return cls(month, day, year)    @staticmethod    def _from_string(date_string):        month, day, year = date_string.split('.')        return Date(month, day, year)    def __repr__(self):        return "%r:%r:%r" % (self.month, self.day, self.year)date = Date(10, 31, 2017)date1 = Date.from_string("10-11-2016")date2 = Date._from_string("10.29.2015")print(type(date))print(type(date1))print(type(date2))print(date)print(date1)print(date2)

结果:这里写图片描述
当然还有:

class Hero:  @staticmethod  def say_hello():     print("Helllo...")  @classmethod  def say_class_hello(cls):     if(cls.__name__=="HeroSon"):        print("Hi Kido")     elif(cls.__name__=="HeroDaughter"):        print("Hi Princess")class HeroSon(Hero):  def say_son_hello(self):     print("test  hello")class HeroDaughter(Hero):  def say_daughter_hello(self):     print("test  hello daughter")testson = HeroSon()testson.say_class_hello() #Output: "Hi Kido"testson.say_hello() #Outputs: "Helllo..."testdaughter = HeroDaughter()testdaughter.say_class_hello() #Outputs: "Hi Princess"testdaughter.say_hello() #Outputs: "Helllo..."

上面两个例子就已经可以很好的阐述了这两种方法的用处了。


好了,今天就到这。谢谢大家。
有问题探讨请加QQ:1043601529

原创粉丝点击