python3:类方法,静态方法和实例方法以及应用场景

1.实例方法

在编程里经常用的是实例方法,直接用实例去调用, 只要 方法里有self 就可以断定是实例方法,
如 def method_name(self,*argc). 先看下边代码如下:

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,day=self.day)

    def yesterday(self):
        self.day-=1

date=Date(2018,10,20)
print(date)

date.yesterday()

print(date)
#打印结果
2018-10-20
2018-10-19

先说下 date.yesterday() ,实例直接调用方法名 ,会转化为 yesterday(date), 改变了实例的属性 day ,这也只是改变了实例的属性,并不会改变类的变量(这个在前面已经讲过了)。如果我就想在方法里改变类的变量怎么做呢?看下边的代码。

class  Date:
    day=10   #添加 类属性 day
    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,day=self.day)

    def yesterday(Date):
        Date.day-=1         #对类进行修改, 记住用的是Date.day ,如果是实例方法必须是 self.

date=Date(2018,10,20)
print(date)
#打印结果    实例传入 day =20, 就用实例的20,不会找 类的a=10
2018-10-20
Date.yesterday(Date)
print(date)
#打印结果 如下, 这个全部用的是类,跟self 没有关系,所以还是打印结果不变。
2018-10-20
print(Date.day)
#打印结果  调用修改类属性方法 生效。  如果self 没有day 这个属性,他一定去找类的变量 day, 这个可以自己尝试下。
9
 

上边的有点扯远了, 也算复习下 类变量和实例变量的关系

2.静态方法

下边正式介绍 静态方法,我们之前想创造一个实例都是用 Date(2018,10,20),现在升级了, 假如我们想传递直接字符串的形式怎么办呢? 例如 “2018-01-01” or “2018/01/01" 如果直接传递百分之百错误。如果不用静态方法,我们首先用到的是,先把 这个字符串转化为 2018,01,01 这种形式再传递, 先看下边的代码就是这样形式。

year,month,day=tuple("2018-10-10".split("-"))
print(year,month,day)
#打印结果   转化成功, 再拿转化后的进行传值,
#2018 10 10

缺点是每次实例化都要调用这段代码,代码量自己想想, 有没有好的方法呢, 就用 静态方法可以解决这个问题,小白该说了,我直接定义个实例化方法不行了吗? 懂行的人会笑坏大牙,这里不做解释了,自己想想吧。
下边就开始用静态方法了 ,代码如下:

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, day=self.day)

    def yesterday(Date):
        Date.day -= 1

    @staticmethod       #  用这个装饰器表明是静态方法,这个要注意。
    def static(date_str):
        year, month, day = tuple(date_str.split("-"))
        return Date(int(year), int(month), int(day))


new_day=Date.static("2018-10-10")    #由于静态方法不属于实例 所以调用的时候, 用类名.静态方法,这个要注意
print(new_day)


#打印结果  正好是咱们的预期结果。
2018-10-10

以上用静态方法初始化数据,代码变短简洁 ,易读性提高。 假如我们要修改类名Date变成New_date,这个时候我们要同时修改所有调用的类名。比如上边的 return Date (int(year), int(month), int(day)),这个就是硬编码的形式。有没有办法不用修改,哈哈 当然有了。就是类方法能解决。

3.类方法

静态方法用 @staticmethod 标识, 类方法同样也有装饰器用 @classmethod ,实例方法传递的是self,类同样也是对象直接传递cls就行。

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, day=self.day)

    def yesterday(Date):
        Date.day -= 1

   # @staticmethod
    #def static(date_str):
     #   year, month, day = tuple(date_str.split("-"))
      #  return Date(int(year), int(month), int(day))

    @classmethod       #类方法的标识
    def class_method(cls,date_str):    # 这个cls只是表明类对象,是可以修改的,同样你改为self也是一样,叫cls为了提高可读性。
        year, month, day = tuple(date_str.split("-"))
        return cls(int(year), int(month), int(day))         #这个cls 和上边是一样的意思,这个就比静态方法好处就是会随便类名变化而变化。

new_day=Date.class_method("2018-10-10")
print(new_day)
#打印结果
2018-10-10

我这样一比较,小伙伴该认为以后就没有用静态方法,反正类方法可以替代并且优越于他,存在就有合理的地方,下边我介绍静态方法的适合他的应用场景之一是校验传入值。请看下边的代码,是类方法和静态方法的结合。

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, day=self.day)

    def yesterday(Date):
        Date.day -= 1

    @staticmethod     #校验输入值类型和大小是否符合咱们的类型。
    def var_str(date_str):
        year, month, day = tuple(date_str.split("-"))
        if 0 < int(year) and 0 < int(month) <= 12 and 0 < int(day) < 32:
            return True
        else:
            return False

    @classmethod
    def class_method(cls, date_str):

        if cls.var_str(date_str):  #这里是调用静态方法,注意要用cls.静态方法,原理和实例方法中的self一样,自己可以试试,否则是不能读取的。
            year, month, day = tuple(date_str.split("-"))
            return cls(int(year), int(month), int(day))


new_day = Date.class_method("2018-10-10")
print(new_day)
# 打印结果
2018 - 10 - 10

总结下 为什么这样结合呢, 校验方法和初始化数据方法分开,代码的逻辑清晰, 就像前端和后端要分离一样的道理。 用的最多的是实例方法。

实例方法 用self标识,一般用实例调用, 静态方法标识是 @staticmethod用类名去调用,类方法优于静态方法解决了静态方法的类名的硬编码, 在不同的场景搭配不同方法为了达到代码的可读性简洁。

你可能感兴趣的:(Python,深入理解类和对象(已完结))