python之装饰器初识

1、@abstractmethod

一、抽象类的做用:规范编程模式
多人开发、复杂的需求、后期的扩展
是一种用来帮助咱们完成规范化的手段编程

二、如何定义抽象类
1,from abc import ABCMeta,abstractmethod
2,在这个类建立的时候指定 metaclass = ABCMeta
3,在你但愿子类要实现的方法的上一行加上一个 @abstractmethod装饰器

三、使用抽象类
1,继承这个类
2,必须实现这个类中被@abstractmethod装饰器装饰的方法微信

四、实例ide

# 支付功能

from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):  # 模板的功能
    @abstractmethod                               # abstractmethod是一个装饰器,装饰器怎么用?放在函数或者类的上一行
    def pay(self): pass

# 这样就构建了一个抽象类Payment,并声明了子类必需要实现的方法是 pay(),若子类没有定义pay(),则实例化时会报错


class Alipay(Payment):  # 继承了抽象类,就必须实现抽象类中被@abstractmethod装饰器装饰的方法 pay()
    def pay(self, money):
        print('使用支付宝支付了%s元' % money)


class Wechatpay(Payment):
    def pay(self, money):
        print('使用微信支付了%s元' % money)


class My_pay(Payment):  # 这里没有定义pay()方法,那么在实例化的时候机会报错
    def fuqian(self,money):
        print('你支付了%s元' % money)


def pay(obj, money):
    obj.pay(money)


# p = Payment()  # 报错 抽象类不能被实例化

a = Alipay()
# a.pay(100)
pay(a,100)  # 使用支付宝支付了100元

we = Wechatpay()
# we.pay(200)
pay(we,200)  # 使用微信支付了200元

my = My_pay()  # 报错:类中没有定义抽象类的pay方法
pay(my,300)
View Code

2、@property  setter deleter

一、
装饰器的分类:
装饰函数
装饰方法 : property
装饰类函数

装饰器函数都怎么用:
在函数、方法、类的上面一行直接@装饰器的名字post

二、property是一个装饰器函数(就是用来解决刚才私有属性的问题)
property:将一个方法假装成一个属性微信支付

2-1学生信息中,姓名不想给别人修改,就设置为私有属性,在定义一个同名的方法假装成属性,便于查找ui

class Student:
    def __init__(self,name,age):
        self.__name = name
        self.age = age

    @property
    def name(self):    # 声明了@property使用此方法的时候就能够不写括号,就假装成了属性
        return self.__name

xiaoming = Student('小明',18)
print(xiaoming.name)  # 小明

xiaoming.name = '小狗'  # 改:报错
print(xiaoming.name)
View Code

 

2-2圆的半径能够修改,可是面积和周长应该是属性的形式比较正确,可是直接设置为属性,圆的半径改了后,
周长和面积并不会改变this

class Circle:
    def __init__(self,r):
        self.r = r
        self.area = 3.14 * self.r ** 2
        self.perimeter = 2 * 3.14 * self.r
c = Circle(6)
print(c.area)  # 113.04
print(c.perimeter)  # 37.68

c.r = 3  # 改变了半径
print(c.area)  # 113.04
print(c.perimeter)  # 37.68
View Code

 

2-3所以上面的圆能够写成这样:spa

class Circle:
    def __init__(self,r):
        self.r = r

    @property
    def area(self):
        return 3.14 * self.r ** 2

    @property
    def perimeter(self):
        return 2 * 3.14 * self.r

c = Circle(6)
print(c.area)  # 113.04
print(c.perimeter)  # 37.68

c.r = 3  # 改变了半径
print(c.area)  # 28.26
print(c.perimeter)  # 18.84
View Code

 

2-4完整的property

一、定义
一个方法被假装成属性以后,应该能够执行一个属性的增删改查操做,
增长和修改就对应着被setter装饰的方法,
删除一个属性对应着被deleter装饰的方法。code

@property:把方法假装成属性

@被property装饰的方法名.setter:
当被property装饰的方法,又实现了一个同名方法,且被setter装饰器装饰了,
那么在对被装饰的方法赋值的时候,就会触发被setter装饰器装饰的方法,
这个方法必需要传一个参数接收等号后面的值,
是用来保护一个变量在修改的时候可以添加一些保护条件。

@被property装饰的方法名.deleter:
当被property装饰的方法,又实现了一个同名方法,且被deleter装饰器装饰了,
那么在对被装饰的方法进行删除的操做时,就会触发被deleter装饰器装饰的方法,
这个方法并不能在执行的时候真的删除这个属性,而是你在代码中执行什么就有什么效果.

二、例题

复制代码
学生类
class Student:
    def __init__(self,name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self,new):
        if type(new) is str:   #由于名字是字符串类型的,咱们这样设置能够保证只能用字符串修更名字
            self.__name = new

    @name.deleter
    def name(self):
        del self.__name

xiaoming = Student('小明')
print(xiaoming.name)   #小明

xiaoming.name = 123   # 不是字符串修改不了
print(xiaoming.name)   # 小明

xiaoming.name = '小花猫'
print(xiaoming.name)   # 小花猫

del xiaoming.name
print(xiaoming.__dict__) # {} 空字典


水果类:
class Fruits:
    __discount = 0.7

    def __init__(self,price):
        self.__price = price

    @property
    def price(self):
        return self.__price * Fruits.__discount

    @price.setter
    def price(self,new):
        if type(new) is int or float:
            self.__price = new

    @price.deleter
    def price(self):
        del self.__price

banana = Fruits(10)
print(banana.price)  # 折扣价7.0


banana.price = 9
print(banana.price) # 折扣价6.3

del banana.price
print(banana.__dict__)  # {} 空字典
复制代码

三、总结

被setter和deleter装饰的方法名必须和被property装饰的方法名一致,对象.方法名 不加括号 能够调用被property装饰的方法,
当对被property装饰的方法赋值时,就会触发被setter装饰的方法,当对被property装饰的方法进行删除del操做时,就会触发
被deleter装饰的方法。
注意:(通常来讲用的最多的是property,其余两个看状况而使用)

 

3、@classmethod

类方法:
用@classmethod装饰
类方法默认形参用cls表示,而不用self
能够直接经过类去修改类的属性,不须要实例化

复制代码
class Fruits:
    __discount = 0.7  # 类的静态属性

    def __init__(self,price):
        self.__price = price  # 对象的私有属性

    @property
    def price(self):
        return self.__price * Fruits.__discount

    @classmethod
    def change_discount(cls,new):  # 类方法默认形参用cls表示,而不用self
        cls.__discount = new


Fruits.change_discount(0.6)
print(Fruits.__dict__)  # '_Fruits__discount': 0.6


类方法的特色:
只使用类中的资源,且这个资源能够直接用类名引用,那这个方法应该被改成一个类方法
复制代码

 

4、@staticmethod

静态方法
被@staticmethod装饰的方法,不使用类中的命名空间也不使用对象的命名空间,
能够传参,也能够不传参,没有默认参数(self,cls),至关于一个类外的普通的方法,
不一样的是调用的时候须要 类名.方法名

复制代码
class Student:
    @staticmethod
    def login():
        print('登陆成功')

Student.login())
复制代码
相关文章
相关标签/搜索