python面对对象编程中会用到的装饰器

1、property

  用途:用来将对像的某个方法伪装成属性来提高代码的统一性。

class Goods:                #商品类
    discount = 0.8            #商品折扣
    def __init__(self,name,price):
        self.name = name
        self.price = price
    def discountprice(self):      #定义goodsprice方法,返回折扣后价格
        return self.price*self.discount
ipad = Goods('ipad',2299)    #实例化商品
print(ipad.name)
print(ipad.discountprice())  #打印商品的的折扣价格
      

  实时上商品的折扣价格应该跟商品的名字一样更像一个对象的属性应该是按照:对象.属性去访问而不是对象.方法()访问,因为抵扣价格更像是商品的属性。而property就可以将方法伪装成对象的属性:

class Goods:
    discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.price = price
    @property    #在要装饰的方法前面加上@property,注意装饰的方法是除了self不能接受参数的
    def discountprice(self):
        return self.price*self.discount

ipad = Goods('ipad',2299)

print(ipad.name)

print(ipad.discountprice)  #可以直接用访问属性的方法得到折扣价。
                 #这样我们就实现了对象访问的一致性。

   既然伪装成了一个属性,那么属性不仅可以访问应该还可以修改和删除,但是你发现你如果调用ipad.discountprice=1000,会执行错误,因为他本身还是个函数,只是被装饰器伪装了所以这里引入property的另外两个方法setter和deleter:      

class Goods:
    discount = 0.8
    def __init__(self,name,price):
        self.name = name
        self.price = price
    @property
    def discountprice(self):
        return self.price*self.discount
    @discountprice.setter      #装饰函数发送修改的值,必须有一个参数
    def discountprice(self,new):
        self.price = new
    @discountprice.deleter
    def discountprice(self):    #装饰函数删除属性
        del self.price


ipad = Goods('ipad',2299)
print(ipad.price)   #2299
print(ipad.discountprice)   #1839.2
ipad.discountprice = 3000    #执行被@discountprice.setter装饰的函数new接受3000
print(ipad.discountprice) #2400 del ipad.discountprice    #删除属性 执行被@discountprice.deleter装饰的函数
print(ipad.discountprice) #报错没有discountprice

#以上就完全将discounsprice伪装成了属性,可以按照属性的查删改去调用discountprice,注意被property、setter、deleter装饰的函数一定要同名

# 一个方法被伪装成属性之后
# 应该可以执行一个属性的增删改查操作
# 那么增加和修改 就对应这被setter装饰的方法 :这个方法又一个必传的参数new,表示赋值的时候等号后面的值
# 删除一个属性 对应着 被deleter装饰的方法,这个方法并不能在执行的时候真的删除这个属性,而是你在代码中执行什么就有什么效果


#classmethod
# 在类中定义一个类方法 、是一个装饰器
# 什么时候用?
# 如果你的整个方法中都没有用到对象命名空间中的名字,且你用到了类的命名空间中的名字(普通方法和property方法除外)
# 类方法的默认参数 : cls 值得是调用这个方法的类
# 类方法的调用方式 : 通过类名调用,本质是方法

 

2、classmethod

  故名思议,类方法装饰器,当执行的方法操作的只有类的静态属性时,这个方法应该是用类本身去调用而不是实例的对象,还是上面的例子我要你用去定义个方法更改类的disount的值你会写出下面的代码

class Goods:
    __discount = 0.8           # 静态属性
    def __init__(self,price):
        self.__price = price   #  对象属性
        self.name = 'apple'

    def price(self):

        return self.__price * Goods.__discount

    def change_discount(self,new):       #方法在对象调用时,函数内部并没有引用对象任何属性 
        Goods.__discount = new
ipad = Goods('ipad',2000)
ipad.chang_discount(0.7)    #这样你虽然实现了更改了类的静态属性,但这在编程上是不规范的:对象通过方法修改类属性,在方法内部没有引用任何对象的属性,
                  #那么把对象调用就多余了,还有类的属性应该由类本身去修改


#修改如下:
class Goods:
__discount = 0.8 # 静态属性
def __init__(self,price):
self.__price = price # 对象属性
self.name = 'apple'

def price(self):

return self.__price * Goods.__discount
@classmethod
def change_discount(clf,new): # 类方法,这样这里的clf就如同对象调用方法自动将对象传入self一样会自动将类自己传入
clf.__discount = new
Goods.change_discount(0.7)  #这样就是类自己调用类方法修改自己的属性,而且只需要输入new的参数即可,crf会自动接收类本身

3、staticmethod

  静态方法,就是通常我们定义的函数,内部既不会引用对象方法属性也不会引用类属性和方法,但是需要你将他放在类里面,这样只是为了纯面向对象编程,外部无函数:

 class Foo:     @classmethod     def class_method(cls):pass     @staticmethod     def static_method():pass
Foo.static()      #通过类调用函数,传参和函数还是一致

# staticmethod
# 将一个普通的函数放到类中来就给这个函数加上一个@staticmethod装饰器
# 这个函数就不需要传默认的参数:self,cls
# 静态方法的调用方式 : 通过类名调用,本质还是函数

 
原文地址:https://www.cnblogs.com/Kingfan1993/p/9566153.html