python笔记(20)--property内置装饰器、method方法和反射(重要)
内容目录
- 内置装饰器函数:property
- method方法
- 反射(重要)
内容回顾
-
接口类和抽象类
- python中没有接口类,有抽象类,abc模块中的metaclass = ABCMeta,方法上引用装饰器@abstructmethod
- 本质是做代码规范用的,希望在子类中实现和父类名字完全一样的方法
- 在java的角度看,是有区别的
- java本来就支持单继承,所以就有了抽象类
- java没有多继承,所以为了接口隔离原则,设计了接口这个概念,支持多继承了
- python既支持单继承也支持多继承,所以对于接口类和抽象类的区别就不那么明显了
- 甚至在python中没有内置接口类
-
多态和鸭子类型
- 多态 -- python天生支持多态
- 鸭子类型 -- 不依赖父类的情况下实现两个相似的类中的同名方法
-
封装 -- 私有的
内容详细
1.property:
-
内置装饰器函数,只能在面向对象中使用
-
把类中的方法变为属性,以供调用,获取方法的返回值
-
注意:方法中不能传值,只是有(self)
from math import pi class Circle: def __init__(self,r): self.r = r @property #方法装饰器 def perimeter(self): return 2*pi*self.r @property #方法装饰器 def area(self): return self.r**2*pi c1 = Circle(5) print(c1.perimeter)#类中对应方法加上装饰器后,调用时不用加括号,可以当成属性用 print(c1.area) count = c1.perimeter + c1.area #类中方法属性调用
2.method方法:staticmathod / classmethod
2.1 classmethod 类方法
-
把一个方法变成原本类中的方法,这个方法可以直接被原类调用,不需要用实例化对象调用
-
应用:可以修改原类中的静态属性
# 商品折扣 class Goods: __discount = 0.8 def __init__(self,name,price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.__discount @classmethod def change_discount(cls,new_discount): cls.__discount = new_discount apple = Goods('苹果',5) print(apple.price) # 4.0 banana = Goods('香蕉',6) print(banana.price) # 4.8 #此时如果想修改全局的折扣属性,则使用classmethod装饰器装饰修改的方法 Goods.change_discount(0.5) apple = Goods('苹果',5) print(apple.price) # 2.5 banana = Goods('香蕉',6) print(banana.price) # 3.0
2.2 staticmathod 静态方法
-
在完全面向对象的程序中使用。
-
可以使类中的方法,直接在外部直接调用
-
如果一个函数,即和对象没关系,也和类没关系,那么使用此方法将这个函数变成一个静态方法
class Login: def __init__(self,name,password): self.name = name self.pwd = password def login(self): pass @staticmethod #使用静态方法 def get_usr_pwd(): user = input('用户名') pwd = input('密码') Login(user,pwd) #传值进入原类中 Login.get_usr_pwd() #类外部直接调用
2.3 总结
- 类方法和静态方法,都是类调用的
- 对象可以调用类方法和静态方法(不推荐)
- 类方法中有一个默认参数 cls 代表这个类 (cls可以修改,不推荐修改cls)
- 静态方法,没有默认参数,就像函数一样
3.反射(重要)
作用:使一个字符串可以变成一个被调用的对象
取类中的静态属性:根据怎么调用来应用,例:类名.属性/方法,使用getattr(类名,'属性/方法') / hasattr(类名,'属性/方法')
-
getattr取值
class Teacher: dic = {'查看学生信息':'show_student','查看讲师信息':'show_teacher'} def show_student(self): print('show_student') def show_teacher(self): print('show_teacher') @classmethod def func(cls): print('hahahah') ret1 = getattr(Teacher,'dic') #使用getattr取类中的静态属性 print(ret1) ret2 = getattr(Teacher,'func') #使用getattr取类中的方法 ret2()
-
hasattr做判断,搭配使用getattr
if hasattr(Teacher,'dic1'): ret = getattr(Teacher,'dic1') print(ret) else: print('不存在')
class Teacher: dic = {'查看学生信息':'show_student','查看讲师信息':'show_teacher'} def show_student(self): print('show_student调取') def show_teacher(self): print('show_teacher调取') @classmethod def func(cls): print('hahahah') alec = Teacher() for item in Teacher.dic: print(item) key = input('》》》') if hasattr(alec,Teacher.dic[key]): #因为Teacher.dic[key]就等于字符串,不需要加引号 func = getattr(alec,Teacher.dic[key]) func() #执行了类中的方法 else: print('不存在')