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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_37720172/article/details/78380893

有时我们会在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().data

print(test.method())

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


三.@classmethod:类方法

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

class test(object):
    def __init__(self):
        self.data = "This is a class"

    @classmethod
    def method(cls):
        return cls.data

print(test.method())

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

class test(object):
    data = "this a class"

    @classmethod
    def method(cls):
        return cls.data

print(test.method())

结果:

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

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

class test(object):
    data = "this a class"

    @classmethod
    def method(cls):
        return cls

print(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

猜你喜欢

转载自blog.csdn.net/weixin_37720172/article/details/78380893