最近有同学在后盾问,什么状况下应用静态方法,什么状况下应用类办法
明天咱们就来捋一下这两个办法的利用场景
首先,咱们来定义一个一般的类,外面都是一般的办法,一般办法又叫实例办法
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”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。