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    好处:不用实例化也是可以获取到该方法(编写该类里面的部分逻辑)

原文地址:https://www.cnblogs.com/wenshu/p/12258018.html