• Day19&20 python基础---面向对象进阶--装饰器函数,反射,内置方法


    一,@property装饰器:将一个方法伪装成属性

      1、一个方法为伪装成属性之后

      2、应该可以执行一个属性的增删改查操作

      3、那么增加和修改,就对应被@setter装饰的方法:这个方法有一个必传的参数new,表示赋值的时候等号后面的值

      4、删除一个属性 对应着 被@deleter装饰的方法,这个方法并不能在执行的时候真的删除这个属性,而是你在代码中执行什么就有什么效果

    class Goods:
        __discount = 0.8  #折扣
        def __init__(self,price):
            self.__price = price
            self.name = 'apple'
        @property     # 只有当被property装饰的方法
        def price(self):  
            return self.__price * Goods.__discount
        @price.settter    # 且被setter装饰器装饰了
        def price(self,new)     # 又实现了一个同名方法
            self.__price = new   #可以用来保护一个变量 在修改的时候能够添加一些保护条件
        @price.deleter    #删除一个property属性的时候会执行被deleter装饰的方法
        def price(self)
             del self.__price
    apple = Goods(10)
    print(apple.price)
    print(apple.__dict__)
    del apple.price
    apple.price = 8   # 且 在 对被装饰的方法 赋值的时候 就出发被setter装饰器装饰的方法
    print(apple.price)
    print(apple.__dict__)
    del apple.name
    print(apple.__dict__)

    二,@classmethod装饰器:在类中定义一个类方法

      类方法的特点:只使用类中的资源,且这个资源可以直接用类名引用形式地使用,那这个方法应该被改为一个类方法

      类方法的默认参数:cls指的时调用这个方法的类

      类方法的调用方式:通过类名调用,本质是方法

      Q:什么时候用?

        如果整个方法中都没有用到对象命名空间中的名字,且你用到了类的命名空间的名字(普通的方法和property方法除外)

    class Goods:
        __discount = 0.8   #静态属性
        def __init__(self,price):
            self.__price = price   #对象属性
            self.name = 'apple'
        @property
        def price(self):
            # print(self)
            return self.__price * Goods.__discount
        @classmethod
        def change_discount(cls,new):    #类方法
            cls.__discount = new
    
    g1 = Goods(10)
    print(g1.price)
    Goods.change_discount(0.7)
    print(g1.price)
    # print(Goods.__dict__)

    三,@staticmethod装饰器 :在类中定义一个函数,这个函数被称为静态方法

      静态方法的特点:

        将一个普通的函数放到类中来就给这个函数加上一个@staticmethod装饰器

        这个函数不需要传默认的参数:self,cls

        静态方法的调用方式:通过类名调用,本质还是函数

    class Foo:
        @classmethod
        def class_method(cls):pass
        @staticmethod
        def static_method():pass
    from types import  MethodType,FunctionType
    obj = Foo()
    print(isinstance(Foo.class_method,MethodType))
    print(isinstance(Foo.static_method,FunctionType))  #是一个函数
    print(obj.static_method)  #<function Foo.static_method at 0x000002D06E725EA0>

    四,类内属性总结:

        静态属性:
            所有对象都统一拥有的属性
            一般被类调用
      类方法:
            如果这个方法涉及到操作静态属性、类方法、静态方法
            默认参数:cls,表示类
            一般被类调用
      静态方法:
            不使用类中或普通方法中的的命名空间也不适用对象的命名空间 : 一个普通的函数方法
            没有默认蚕食
            一般被类调用
          方法:    
            普通方法
            默认参数:self,表示对象
            一般被对象调用
          property方法:
            默认参数:self,表示对象       
            一般被对象调用

    五,isinstance & issubclass

      isinstance:判断对象和类之间的关系

      特点:判断这个对象是否是这个类、这个类的子类的对象

      issubclass:判断类和类之间的关系

      特点:判断一个类是否是另一个类的子类

    #检测对象与类之间的关系
    class
    A:pass class B(A):pass a = A() b = B() print(type(a) is A) print(type(b) is B) print(type(b) is A) print(isinstance(a,A)) print(isinstance(b,A)) print(isinstance(a,B)) print(type(123) is int) #对比 print(isinstance(123,int))
    #检测类与类之间的关系
    class A:pass
    class B(A):pass
    print(issubclass(A,B))
    print(issubclass(B,A))

    六,反射

      Q1:什么是反射

          使用字符串数据类型的变量名来获取这个变量的值

      

      Q2:为什么需要反射(三个场景

       #input:

         #用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的时name,就打印alex

         #文件

           #从文件中读出的字符串,想转换成变量的名字

             #网络

                  #将网络传输的字符串转换成变量的名字

      

      Q3:反射的用法与应用

      getattr和hasattr方法解析:

      getattr(变量名:命名空间,字符串:属于一个命名空间内的变量名),如果该变量存在于这个命名空间,则返回该变量名,否则报错

      hasattr(变量名:命名空间,字符串:属于一个命名空间内的变量名),如果该变量存在于这个命名空间,则返回True,否则返回False

      

      #反射类中的变量:静态属性,类方法,静态方法

    #反射类中的变量:静态属性,类方法,静态方法
    class
    Foo: School = 'oldboy' Country = 'China' language = 'Chinese' @classmethod def class_method(cls): print(cls.School) @staticmethod def static_method(): print('in staticmethod') def func(self): print(666) print(Foo.School) print(Foo.Country) print(Foo.language) #输入属性名并打印 #判断实现 inp = input('>>>').strip() if inp == 'School':print(Foo.School) elif inp == 'Country':print(Foo.Country) elif inp == 'language':print(Foo.language) #反射实现 while 1: inp = input('>>>').strip() print(getattr(Foo,inp))
    getattr(Foo,'School')  #Foo.School
    print(Foo.class_method)
    print(getattr(Foo,'class_method'))
    getattr(Foo,'class_method')()   #Foo.class_method()
    getattr(Foo,'static_method')()  #Foo.static_method()
    getattr(Foo,'func')(1)  #Foo.func(1)
    #检测类中是否有此静态属性名或方法名
    print(hasattr(Foo,'func'))
    print(hasattr(Foo,'fu'))
    
    #反射实现:
    while 1:
        inp = input('>>>').strip()
        if hasattr(Foo,inp):
            print(getattr(Foo,inp))

      #反射对象中的变量

    #反射对象中的变量(对象属性,普通方法)
    class
    Foo: def __init__(self,name,age): self.name = name self.age = age def eating(self): print('%s is eating'%self.name) alex = Foo('alex',33) print(getattr(alex,'name')) print(getattr(alex,'age')) getattr(alex,'eating')()

      #反射模块中的变量

    #反射模块中的变量
    import os
    os.rename('xx.py')
    getattr(os,'rename')('xx.py')

      #反射本文件中的变量

    # 反射本文件中的变量
    a = 1
    b = 2
    name = 'alex'
    def func():
        print('func')
    class Foo:pass
    
    import sys
    print(sys.modules['__main__'])  # 本文件的命名空间
    print(sys.modules)  # 查看所有文件的命名空间
    print(sys.modules['__main__'].a)  #查看本文件的命名空间中a的值
    # __name__变量,内置的变量__name__等于'__main__'
    print(sys.modules[__name__]) #反射本文件中变量 固定的使用这个命名空间
    print(getattr(sys.modules[__name__],'a'))
    print(getattr(sys.modules[__name__],'b'))
    print(getattr(sys.modules[__name__],'name'))
    getattr(sys.modules[__name__],'func')()
    print(getattr(sys.modules[__name__],'Foo'))
    obj = getattr(sys.modules[__name__],'Foo')()
    print(obj)

      setattr(变量名:命名空间,字符串:属于一个命名空间内的变量名,变量值),如果该变量名存在于这个命名空间,则修改该变量对应的值,否则增加这个属性

      delattr(变量名:命名空间,字符串:属于一个命名空间内的变量名),如果该变量存在于这个命名空间,则执行删除操作,否则报错

    #setattr
    class
    Foo: Country = 'China' def func(): print(666) setattr(Foo,'School','OLDBOY') # 接受三个参数 命名空间 ‘变量名’ 变量值 print(getattr(Foo,'School')) setattr(Foo,'School','OLDLADY') print(Foo.School) setattr(Foo,'func',func) # 一般没人往空间中添加函数 print(Foo.__dict__) # 'func': <function func at 0x000001D657AF5E18> Foo.func()
    #delattr
    del Foo.Country
    print(Foo.__dict__)
    delattr(Foo,'Country')
    print(Foo.__dict__)

    七,内置方法

      在不是需要程序员定义,本身就存在在类中的方法就是内置方法

      内置方法的结构:__名字__

      通称:双下方法,魔术方法,内置方法

      所有的双下方法都不需要我们直接去调用,都有另外一种自动触发它的语法

      #__init__:

        不需要我们主动调用,而是在实例化的时候内部自动调用的

      #__str__ :

        当你打印一个对象的时候,触发__str__

        当你使用%s格式化的时候,触发__str__

        str强转数据类型的时候,触发__str__

      #__repr__:

        repr是str的备胎

        有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__

        repr(obj)内置函数对应的结果是__repr__的返回值

        当你使用%r格式化的时候,触发__repr__

    class Course:
        def __init__(self,name,period,price,teacher):
            self.name = name
            self.period = period
            self.price = price
            self.teacher = teacher
        def __str__(self):
            return 'str: %s %s %s %s' % (self.name,self.period,self.price,self.teacher)
        def __repr__(self):
            return 'repr: %s %s %s %s' % (self.name, self.period, self.price, self.teacher)
    course_lst = []
    python = Course('python','6 month',29800,'oldboy')
    course_lst.append(python)
    linux = Course('linux','5 month',25800,'oldboy')
    course_lst.append(linux)
    for id,course in enumerate(course_lst,1):
        print(id,course)
        print('%s %s'%(id,course))
        print(str(course))
        print(repr(course))
        print('%r'%course)
    #继承关系中的__str__和__repr__寻找顺序
    class Foo:
        def __str__(self):  #2
            return 'Foo.str'
        def __repr__(self):   #4
            return 'Foo.repr'
    class Son(Foo):
        def __str__(self):   #1
            return 'Son.str'
        def __repr__(self):  #3
            return 'Son.repr'
    s1 = Son()
    print(s1)

      

  • 相关阅读:
    企业项目化管理介绍
    企业IT架构介绍
    移动端运维体系建设
    学习型组织与企业
    css垂直居中怎么设置?文字上下居中和图片垂直居中
    情人节看看他们是怎么用微信红包示爱的
    2017年腾讯首次大规模扫号展开
    随机森林入门攻略(内含R、Python代码)
    11 Facts about Data Science that you must know
    机器学习编程语言之争,Python夺魁
  • 原文地址:https://www.cnblogs.com/lianyeah/p/9568530.html
Copyright © 2020-2023  润新知