修饰器 @classmethod 、@property 、@staticmethod 的用法

都是使用在类中的。

--------------------------------------------------------------------------------------------------------------------------------

class cal:
     cal_name = '计算器'
     def __init__(self,x,y):
         self.x = x
         self.y = y
 
     @property           #在cal_add函数前加上@property,使得该函数可直接调用,封装起来

     def cal_add(self):
         return self.x + self.y
 
     @classmethod        #在cal_info函数前加上@classmethon,则该函数变为类方法,该函数只能访问到类的数据属性,不能获取实例的数据属性
 
   def cal_info(cls):  #python自动传入位置参数cls就是类本身
     
   print('这是一个%s'%cls.cal_name)   #cls.cal_name调用类自己的数据属性
 
     @staticmethod       #静态方法 类或实例均可调用
   
 def cal_test(a,b,c): #该静态方法函数里不传入self 或 cls
         
print(a,b,c)
c1 = cal(10,11)
cal.cal_info()          #>>> 这是一个计算器    
cal.cal_test(1,2,3)     #>>> 1 2 3
c1.cal_test(1,2,3)      #>>> 1 2 3

-----------------------------------------------------------------------------------------------------------------------------------------

一、@classmethod  和@staticmethod 的区别?

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。 
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。 
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。

既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢 
从它们的使用上来看,

  • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

    如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。 
    而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

 

二、 @property  

在我们定义数据库字段类的时候,往往需要对其中的类属性做一些限制,一般用get和set方法来写,那在python中,我们该怎么做能够少写代码,又能优雅的实现想要的限制,减少错误的发生呢,这时候就需要我们的@property

eg:

class Student(object):

    def get_score(self):
        return self._score

    def set_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
调用:

>>> s = Student()           

>>> s.set_score(60) # ok!

>>> s.get_score()   #60

 #先实例化,然后实例化对象.方法  获取类属性值   

到这里,可能觉得每次都要这样来修改属性值比较麻烦,那么我想直接 实例化对象.方法 【s.score】,@property使方法像属性一样调用,就像是一种特殊的属性

 

如下

 

class Student(object):

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

    @score.setter
    def score(self,value):
        if not isinstance(value, int):
            raise ValueError('分数必须是整数才行呐')
        if value < 0 or value > 100:
            raise ValueError('分数必须0-100之间')
        self._score = value
 

调用:

>>> s = Student()

>>> s.score = 60 # OK,实际转化为s.set_score(60)

>>> s.score # OK,实际转化为s.get_score()

 

 

 

=======【补充知识】====================================================================

在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name、__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如__name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
修饰器 @classmethod 、@property 、@staticmethod 的用法