一、@abstractmethod
1、抽象类的作用:规范编程模式
多人开发、复杂的需求、后期的扩展
是一种用来帮助我们完成规范化的手段
2、如何定义抽象类
1,from abc import ABCMeta,abstractmethod
2,在这个类创建的时候指定 metaclass = ABCMeta
3,在你希望子类要实现的方法的上一行加上一个 @abstractmethod装饰器
3、使用抽象类
1,继承这个类
2,必须实现这个类中被@abstractmethod装饰器装饰的方法
4、实例
# 支付功能 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)
二、@property setter deleter
1、
装饰器的分类:
装饰函数
装饰方法 : property
装饰类
装饰器函数都怎么用:
在函数、方法、类的上面一行直接@装饰器的名字
2、property是一个装饰器函数(就是用来解决刚才私有属性的问题)
property:将一个方法伪装成一个属性
2-1学生信息中,姓名不想给别人修改,就设置为私有属性,在定义一个同名的方法伪装成属性,便于查找
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)
2-2圆的半径可以修改,但是面积和周长应该是属性的形式比较正确,但是直接设置为属性,圆的半径改了后,
周长和面积并不会改变
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
2-3因此上面的圆可以写成这样:
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
2-4完整的property
1、定义
一个方法被伪装成属性之后,应该可以执行一个属性的增删改查操作,
增加和修改就对应着被setter装饰的方法,
删除一个属性对应着被deleter装饰的方法。
@property:把方法伪装成属性
@被property装饰的方法名.setter:
当被property装饰的方法,又实现了一个同名方法,且被setter装饰器装饰了,
那么在对被装饰的方法赋值的时候,就会触发被setter装饰器装饰的方法,
这个方法必须要传一个参数接收等号后面的值,
是用来保护一个变量在修改的时候能够添加一些保护条件。
@被property装饰的方法名.deleter:
当被property装饰的方法,又实现了一个同名方法,且被deleter装饰器装饰了,
那么在对被装饰的方法进行删除的操作时,就会触发被deleter装饰器装饰的方法,
这个方法并不能在执行的时候真的删除这个属性,而是你在代码中执行什么就有什么效果.
2、例题
学生类 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__) # {} 空字典
3、总结:
被setter和deleter装饰的方法名必须和被property装饰的方法名一致,对象.方法名 不加括号 可以调用被property装饰的方法,
当对被property装饰的方法赋值时,就会触发被setter装饰的方法,当对被property装饰的方法进行删除del操作时,就会触发
被deleter装饰的方法。
注意:(一般来说用的最多的是property,其他两个看情况而使用)
三、@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 类方法的特点: 只使用类中的资源,且这个资源可以直接用类名引用,那这个方法应该被改为一个类方法
四、@staticmethod
静态方法
被@staticmethod装饰的方法,不使用类中的命名空间也不使用对象的命名空间,
可以传参,也可以不传参,没有默认参数(self,cls),相当于一个类外的普通的方法,
不同的是调用的时候需要 类名.方法名
class Student: @staticmethod def login(): print(‘登录成功‘) Student.login())