zoukankan      html  css  js  c++  java
  • staticmethod&classmethod&property

    property

    是将一个方法变成属性
    class Student(object):

    @property
    def score(self):
    return self._score

    @score.setter
    def score(self, value):
    if not isinstance(value, int):
    raise ValueError('score must be an integer!')
    if value < 0 or value > 100:
    raise ValueError('score must between 0 ~ 100!')
    self._score = value
    @property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

    >>> s = Student()
    >>> s.score = 60 # OK,实际转化为s.set_score(60)
    >>> s.score # OK,实际转化为s.get_score()
    60
    >>> s.score = 9999
    Traceback (most recent call last):
    ...
    ValueError: score must between 0 ~ 100!
    注意到这个神奇的@property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。

    还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

    class Student(object):

    @property
    def birth(self):
    return self._birth

    @birth.setter
    def birth(self, value):
    self._birth = value

    @property
    def age(self):
    return 2014 - self._birth
    上面的birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。

    staticmethod &&

    staticmethod和classmethod的区别:

    @staticmethod 不需要访问和类相关的属性或数据(感觉只是概念上的区别,你这样声明了用的人就知道了,如果你非要在这个方法中访问test.xxx 它就和@classmethod的作用一样了。)

    @classmethod 可以访问和类相关(不和实例相关)的属性,看 test.my_class_print("class print") 和 my_test.my_class_print("class print") 的结果都是class中定义的class_name  的值,非实例的值:xxx

    如果你定义了一个方法它的返回值永远和类的属性及实例无关,结果永远不变,就用@staticmethod

    如果你定义了一个方法它的返回值和只和类的属性有关,结果可变(比如上例,我用test.class_name="AAA"改变类的属性值,my_class_print输出的结果就改变了) .就用@classmethod

    class Date:

        hour = 1

        def __init__(self,year,month,day):

            self.year = year

            self.month  = month

            self.day = day

        def tomorrow(self):    #实例方法

            self.day += 1     #修改的当前实例的值,不影响类和其他实例

            Date.hour +=1      

    #修改的是类变量的值,只要有实例改变这个值,这个类和其他的实例的该值都会变化

    # 如果有值修改过这个值,后续所有该类的实例和该类的这个值都会是修改过后的值。

    @staticmethod

        def parse_from_str(date_str):   #静态方法不需要接收self,函数的调用需要加Date

        year,month,day = tuple(date_str.split('-'))

        # return  Date(int(year),int(month),int(day))

        return  123

        # 静态方法直接使用类调用就可以,实例也是可以进行调用的,但是类是无法调用实例方法

        # 静态方法缺点:         return  Date(int(year),int(month),int(day)) ,Date是硬编码,如果类名修改了,这里就会报错

        # 静态方法优点:  可以写一些属于该类的代码逻辑在里面

    @classmethod

    def from_string(cls, date_str):

        year, month, day = tuple(date_str.split('-'))   # 类方法直接使用类调用就可以,实例也是可以进行调用的,但是类是无法调用实例方法

        return cls(int(year), int(month), int(day))     # 优点:修改了硬编码的方式,类的名称可以随意去修改

        def __str__(self):

            return "{year}/{month}/{day}/{hour}".format(year=self.year,month=self.month,day=self.day,hour=self.hour)

        # 定义__str__,在打印实例对象(调用)的时候默认输出__str__,不加上__str__方法的时候,调用print是输出实例对象

    if __name__=="__main__":

        new_day3= Date(2018, 11, 22)

        print(new_day3)

        new_day = Date(2018,11,22)

        new_day.tomorrow()

        print(new_day)

        print(Date(2018,11,22))

        new_day1 = Date(2018, 11, 22)

        print(new_day1)

        new_day = Date(2018, 11, 22)

        print(new_day)

    静态方法:@staticmethod

    类方法  @classmethod    好处:不用实例化也是可以获取到该方法(编写该类里面的部分逻辑)

  • 相关阅读:
    Linux基础命令---mv
    Linux服务器---基础设置
    Linux基础命令---find
    Linux服务器配置---安装centos
    Linux基础命令---ls
    Linux基础命令---rmdir
    Linux基础命令---chown
    Linux基础命令---chmod
    Linux基础命令---chgrp
    Linux基础命令---ln
  • 原文地址:https://www.cnblogs.com/wenshu/p/12258018.html
Copyright © 2011-2022 走看看