Python中的类方法、静态方法和实例方法

类方法、静态方法和实例方法

一、实例方法

先定义一个输出日期的类Date,后面内容都是基于此类进行拓展。

class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
	def __str__(self):
        return "{year}/{month}/{day}".format(year=self.year,month=self.month,say=self.day)
    
if __name__ == "__main__":
    new_day = Date(2018,12,30)
    print(new_day) # 2018/12/30   

普通情况下类内定义的都是实例方法,比如上述代码中的__init__()__str__()都是实例方法。

比如在一开始的Date类中再新定义一个实例方法tomorrow。该方法使日期数加一(在这为了简单就不做日期的判断了)。

def tomorrow(self):
    self.day += 1
    
if __name__ == "__main__":
    new_day = Date(2018,12,30)
    new_day.tomorrow() # python会自动转换成tomorrow(new_day)这种形式
    print(new_day) # 2018/12/31  

实例方法是针对实例进行操作,像self.变量+赋值符号就变成了实例对象的变量,而修改类变量则要用类名.变量+赋值符号

二、静态方法

先引入这样一个场景,假设Date类传入的字符串参数是2018-12-31这个样子的。而我们一开始定义的传入参数是用逗号隔开的,所以肯定不行。

那为了达到这样的目的,先想到的最简单的办法就是用split函数,将字符串处理一下,再放进去。

date_str = "2018-12-30"
year, month, day = tuple(data_str.split("-"))
# print(year,month,day) # 2018 12 30
new_day = Date(int(year),int(month),int(day))
print(new_day) # 2018/12/30

可以想到在Date类中并没有提供可以将字符串转换成标准输入的方法。所以就有了自己先处理一下再输入的方法。

这种方法有一个很大的问题,就是每一次实例化Date类时,都需要加上一段处理字符串的代码(即year, month, day = tuple(data_str.split("-")))。

但实际上我们可以把这种逻辑放到类中,也就是定义静态方法。

@staticmethod
def parse_from_string(data_str):
    year, month, day = tuple(data_str.split("-"))
    return Date(int(year),int(month),int(day))

python中静态方法不用接收self

因为在Date类的命名空间中,所以要使用Date.parse_from_string()进行调用

#用staticmethon完成初始化
new_day = Date.prase_from_string(date_str)
print(new_day) # 2018/12/30

此时代码就变得简洁了,而且还可以在静态方法中再增加新的逻辑。但静态方法的的缺点就是因为使用硬编码的方式,如果类名改为NewDate,那么静态方法中返回的Date也要变为NewDate,类多的时候会很麻烦。

所以就有了Python中的类方法。

三、类方法

@classmethod
def from_string(cls,data_str):
    year, month, day = tuple(data_str.split("-"))
    return cls(int(year),int(month),int(day))

__init__(self)传递进来的self是指对象,而from_string()传递进来的cls是指类本身。所以此时return的就与类名没有关系了。

#用classmethon完成初始化
new_day = Date.prase_from_string(date_str)
print(new_day) # 2018/12/30

那我们是不是觉得classmethod就可以完全替代staticmethod

staticmethod当然还有别的用处,我们再设想一个场景,判断字符串是否合法。这个用classmethod也是可以的,但是多想一下,做判断这个逻辑并不用返回这个字符串对象,没有必要用classmethoncls传递进来。

@staticmethod
def valid(data_str):
    year, month, day = tuple(data_str.split("-"))
    if int(year)>0 and (int(month)>0 and month<=12) and (int(day)>0 and int(day)<=31) #简单的逻辑,实际中判断是否合法不是这样的
    	return True
    elsereturn False
    
print(Date.valid_str("2018-12-32")) # False    

小节

静态方法,类方法前边需要加一个装饰器

猜你喜欢

转载自blog.csdn.net/weixin_43901214/article/details/106911827