最近有同学在后盾问,什么状况下应用静态方法,什么状况下应用类办法

明天咱们就来捋一下这两个办法的利用场景

首先,咱们来定义一个一般的类,外面都是一般的办法,一般办法又叫实例办法

class People:    def __init__(self, name, age):        self.name = name        self.age = age    def introduce_myself(self):        print(f'大家好,我叫: {self.name}')    def add_two_string_num(self, a, b):        a_int = int(a)        b_int = int(b)        return a_int + b_int    def calc_age_after_n_year(self, n):        age = self.add_two_string_num(self.age, n)        print(f'{n}年当前,我{age}岁')

这个类运行起来的成果如下图所示:

大家留神在这个类外面的办法add_two_string_num,它承受两个参数,并将他们转换为int类型,而后相加并返回后果。这个过程非常简单,然而,它跟People这个类有什么间接关系吗?

其实这个办法跟这个类没有什么间接关系,咱们甚至把它改成函数都能够:

def add_two_string_num(a, b):    a_int = int(a)    b_int = int(b)    return a_int + b_intclass People:    def __init__(self, name, age):        self.name = name        self.age = age    def introduce_myself(self):        print(f'大家好,我叫: {self.name}')    def calc_age_after_n_year(self, n):        age = add_two_string_num(self.age, n)        print(f'{n}年当前,我{age}岁')        kingname = People('kingname', 20)kingname.introduce_myself()kingname.calc_age_after_n_year(10)

运行后果跟之前齐全一样:

咱们能够说,add_two_string_num函数就是一个工具函数。工具函数接管参数,输入后果,齐全不关怀谁在调用他,也不关怀在哪里调用他。

但当初有一个比拟难堪的事件,这个函数,只有 People在调用,其它中央都没有调用。独自把它放到其它中央又显得多余,弄成实例办法又节约了self参数,这个时候,咱们就能够用静态方法:

class People:    def __init__(self, name, age):        self.name = name        self.age = age    def introduce_myself(self):        print(f'大家好,我叫: {self.name}')    @staticmethod    def add_two_string_num(a, b):        a_int = int(a)        b_int = int(b)        return a_int + b_int    def calc_age_after_n_year(self, n):        age = People.add_two_string_num(self.age, n)        print(f'{n}年当前,我{age}岁')kingname = People('kingname', 20)kingname.introduce_myself()kingname.calc_age_after_n_year(10)
一句话总结:静态方法就是某个类专用的工具函数。

说完了静态方法,咱们再说说类办法。什么状况下应该应用类办法呢?答复这个问题前,我先反诘你一个问题,怎么把People类初始化成一个实例?

你说这还不简略吗,一行代码就行了啊:

xxx = People('xxx', 10)

留神,这里你在初始化这个类的时候,你是一个一个参数传入进去的。如果你用过顺丰寄送快递,你就会发现,填写收件人的时候,有两种形式,一种形式就像下面这样,一个一个参数填进去。另一种形式,它给你一个输入框,你把一段蕴含姓名,地址,手机号的文字粘贴进去,它主动解析。

那么,如果我当初给你一个字符串:我的名字:青南,我的年龄:20,把它提取进去。你怎么基于这个字符串生成People类的实例?

这个时候,你可能会这样写:

import recontent = '我的名字:青南,我的年龄:20,把它提取进去'name = re.search('名字:(.*?),', content).group(1)age = re.search('年龄:(\d+)', content).group(1)kingname = People(name, age)

这样做的确能够,但我能不能让People这个类自动识别呢?其实是能够的,有两种办法,一种办法是在__init__外面多加几个参数,而后在初始化的时候,从这几个参数外面解析,这个办法大家都晓得,我就不多讲了。咱们来讲讲第二个办法,就是应用类办法。

咱们只须要再定义一个类办法:

import reclass People:    def __init__(self, name, age):        self.name = name        self.age = age    def introduce_myself(self):        print(f'大家好,我叫: {self.name}')    @staticmethod    def add_two_string_num(a, b):        a_int = int(a)        b_int = int(b)        return a_int + b_int    @classmethod    def from_chinese_string(cls, sentence):        name = re.search('名字:(.*?),', content).group(1)        age = re.search('年龄:(\d+)', content).group(1)        return cls(name, age)    def calc_age_after_n_year(self, n):        age = People.add_two_string_num(self.age, n)        print(f'{n}年当前,我{age}岁')        content = '我的名字:青南,我的年龄:20,把它提取进去'kingname = People.from_chinese_string(content)kingname.introduce_myself()kingname.calc_age_after_n_year(10)

运行成果如下图所示:

类办法应用装璜器@classmethod来装璜,并且它的第一个参数是隐式参数cls。这个参数其实就是People这个类自身。这个隐式参数在咱们调用类办法的时候,是不须要传入的。在这个类办法外面,相当于应用People初始化了一个实例,而后把这个实例返回了进来。

这样做有什么益处呢?益处就在于咱们齐全不须要批改__init__,那么,也就不须要批改代码外面其它调用了People类的中央。例如当初我又想减少从英文句子外面提取名字和年龄的性能,那么只须要再增加一个类办法就能够了:

import reclass People:    def __init__(self, name, age):        self.name = name        self.age = age    def introduce_myself(self):        print(f'大家好,我叫: {self.name}')    @staticmethod    def add_two_string_num(a, b):        a_int = int(a)        b_int = int(b)        return a_int + b_int    @classmethod    def from_chinese_string(cls, sentence):        name = re.search('名字:(.*?),', content).group(1)        age = re.search('年龄:(\d+)', content).group(1)        return cls(name, age)    @classmethod    def from_english_string(cls, sentence):        name = re.search('name: (.*?),', content).group(1)        age = re.search('age: (\d+)', content).group(1)        return cls(name, age)    def calc_age_after_n_year(self, n):        age = People.add_two_string_num(self.age, n)        print(f'{n}年当前,我{age}岁')        content = 'my name: kinganme, my age: 15 please extract them'kingname = People.from_english_string(content)kingname.introduce_myself()kingname.calc_age_after_n_year(10)

运行成果如下图所示:

一句话总结:当你想应用工厂模式,依据不同的参数生成同一个类的不同对象的时候,就能够应用类办法。

其实如果大家应用过Python自带的datetime模块,你就会发现类办法无处不在:

import datetimenow = datetime.datetime.now()dt = datetime.datetime.fromtimestamp(1633691412)dt2 = datetime.datetime.fromisoformat('2021-10-08 19:10:05')

这段代码外面的.now().fromtimestamp()和 .fromisoformat(),都是类办法。他们最终返回的都是datetime.datetime对象,区别在于他们是依据不同类型的输出参数生成的。

以上就是本次分享的所有内容,如果你感觉文章还不错,欢送关注公众号:Python编程学习圈,每日干货分享,发送“J”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。