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('不存在')
    
posted @ 2020-05-22 18:02  薛定谔的猫儿  阅读(167)  评论(0编辑  收藏  举报