zoukankan      html  css  js  c++  java
  • (转)python3:类方法,静态方法和实例方法以及应用场景

    原文:https://blog.csdn.net/qq_34979346/article/details/83212716

    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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    先说下 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    上边的有点扯远了, 也算复习下 类变量和实例变量的关系。

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

    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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    以上用静态方法初始化数据,代码变短简洁 ,易读性提高。 假如我们要修改类名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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    我这样一比较,小伙伴该认为以后就没有用静态方法,反正类方法可以替代并且优越于他,存在就有合理的地方,下边我介绍静态方法的适合他的应用场景之一是校验传入值。请看下边的代码,是类方法和静态方法的结合。

    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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    总结下 为什么这样结合呢, 校验方法和初始化数据方法分开,代码的逻辑清晰, 就像前端和后端要分离一样的道理。 用的最多的是实例方法。

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

  • 相关阅读:
    LD_PRELOAD的偷梁换柱之能
    ATOM & Sublime Text 下MarkDown插件功能比较
    存在
    2017年执行计划
    2015年总结以及2016年计划
    2014年总结以及2015年计划
    asp.net MVC中form提交和控制器接受form提交过来的数据
    2013年回顾及2014年计划
    c# XML序列化与反序列化
    Namenode HA原理详解(脑裂)
  • 原文地址:https://www.cnblogs.com/liujiacai/p/11139669.html
Copyright © 2011-2022 走看看