zoukankan      html  css  js  c++  java
  • 面向对象----反射

    一,isinstance和issubclass

    isinstance(obj,cls)检查obj是否是类cls的对象

    issubclass(sub,super)检查sub类是否是super类的子类

    # class A:
    #     pass
    # class B(A):pass
    # a=A()
    # b=B()
    # print(issubclass(B,A))      #判断一个类是否为一个类的子类
    # print(isinstance(a,A))      #判断对象是否为类的对象
    # print(isinstance(b,A))

    二,反射

    1,什么是反射?

    主要是指程序可以访问、检测、和修改它本身状态或行为的一种能力。

    2,python面向对象中的反射:通过字符串的形式操作对象相关的属性(就是用字符串类型的名字去操作变量),python中一切事物皆对象(都可以使用反射)

    四个实现反射的函数

    1,getattr,hasattr(一般一起用)

    # class A:pass
    # class B(A):pass
    # a = A()
    # print(isinstance(a,A))
    # print(issubclass(B,A))
    # print(issubclass(A,B))
    
    # 反射 : 是用字符串类型的名字 去操作 变量
    # name = 1
    # eval('print(name)')  # 安全隐患
    
    # 反射 就没有安全问题
    
    # 反射 : 是用字符串类型的名字 去操作 变量
    
    
    # 反射对象中的属性和方法   # hasattr getattr setattr delattr
    # class A:
    #     def func(self):
    #         print('in func')
    #
    # a = A()
    # a.name = 'alex'
    # a.age = 63
    # # 反射对象的属性
    # ret = getattr(a,'name')  # 通过变量名的字符串形式取到的值
    # print(ret)
    # print(a.__dict__)
    # 变量名 = input('>>>')   # func
    # print(getattr(a,变量名))
    # print(a.__dict__[变量名])
    #
    # # 反射对象的方法
    # a.func()
    # ret = getattr(a,'func')
    # ret()
    #
    # class A:
    #     price = 20
    #     @classmethod
    #     def func(cls):
    #         print('in func')
    # # 反射类的属性
    # # A.price
    # print(getattr(A,'price'))
    #
    # # 反射类的方法 :classmethod staticmethod
    # # A.func()
    # if hasattr(A,'func'):
    #     getattr(A,'func')()
    
    #模块
    # import my
    # 反射模块的属性
    # print(my.day)
    # print(getattr(my,'day'))
    
    # 反射模块的方法
    # getattr(my,'wahaha')()
    
    # 内置模块也能用
    # time
    # asctime
    # import time
    # print(getattr(time,'time')())
    # print(getattr(time,'asctime')())
    
    # def qqxing():
    #     print('qqxing')
    # year = 2018
    # import sys
    # # print(sys.modules['__main__'].year)
    # # 反射自己模块中的变量
    # # print(getattr(sys.modules['__main__'],'year'))
    #
    # # 反射自己模块中的函数
    # # getattr(sys.modules['__main__'],'qqxing')()
    # 变量名 = input('>>>')
    # print(getattr(sys.modules[__name__],变量名))
    
    # 反射的函数有参数
    # print(time.strftime('%Y-%m-%d %H:%M:S'))
    # print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))
    
    # 一个模块中的类能反射得到
    # import my
    # print(getattr(my,'C')())
    # if hasattr(my,'name'):
    #     getattr(my,'name')
    用法演示

    2,setattr设置修改变量

    # class A:
    #     pass
    # a=A()
    # setattr(a,"name","nezha")
    # setattr(A,"name","fg")
    # print(a.name)
    # print(A.name)

    3,delattr删除

    # 删除  delattr
    # delattr(a,"name")
    # print(a.name)

    三,双下方法

    1,__str__和__repr__

    # obj.__str__  str(obj)
    # obj.__repr__ repr(obj)
    # class Teacher:
    #     def __init__(self,name,salary):
    #         self.name = name
    #         self.salary = salary
    #     def __str__(self):
    #         return "Teacher's object :%s"%self.name
    #     def __repr__(self):
    #         return str(self.__dict__)
    #     def func(self):
    #         return 'wahaha'
    # nezha = Teacher('哪吒',250)
    # print(nezha)  # 打印一个对象的时候,就是调用a.__str__
    # print(repr(nezha))
    # print('>>> %r'%nezha)
    #a.__str__ --> object
    # object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址
    # l = [1,2,3,4,5]   # 实例化 实例化了一个列表类的对象
    # print(l)
    # %s str()  直接打印 实际上都是走的__str__
    # %r repr()  实际上都是走的__repr__
    # repr 是str的备胎,但str不能做repr的备胎
    
    # print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串
    # 如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。
    # repr(),只会找__repr__,如果没有找父类的
    View Code

    2,__len__

    # 内置的方法有很多
    # 不一定全都在object中
    # class Classes:
    #     def __init__(self,name):
    #         self.name = name
    #         self.student = []
    #     def __len__(self):
    #         return len(self.student)
    #     def __str__(self):
    #         return 'classes'
    # py_s9= Classes('python全栈9期')
    # py_s9.student.append('二哥')
    # py_s9.student.append('泰哥')
    # print(len(py_s9))
    # print(py_s9)
    View Code

    3,__del__

    析构方法,当对象在内存中被释放,自动触发执行。

    此方法一般无需定义,因为python是一门高级语言,析构函数的调用是由解释器自动触发。

    # class A:
    #     def __del__(self):
    #         print("爸爸执行了")
    # a=A()
    # del a
    # print(">>>>")

    4,__call__

    对象后面加括号,触发执行。

    构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()

    class A:
    
        def __init__(self, name):
            self.name = name
    
        def __call__(self):
            '''
            打印这个对象中的所有属性
            :return:
            '''
            for k in self.__dict__:
                print(k, self.__dict__[k])
    b= A('alex')()   #执行__call__
    #name alex
    
    class A:
        def __init__(self):
            print("sd")
        def __call__(self):
            print("ahi")
    a=A()
    a()
    A()()
    #结果
    # sd
    # ahi
    # sd
    # ahi
    View Code

     5,item系列

    getitem  /  setitem  /delitem
    
    # class Foo:
    #     def __init__(self,name,age):
    #         self.name=name
    #         self.age=age
    #     def __getitem__(self, item):
    #         if hasattr(self, item):
    #             return self.__dict__[item]      #查
    #     def __setitem__(self, key, value):
    #         self.__dict__[key]=value          #增 改
    #     def __delitem__(self, key):
    #         del self.__dict__[key]        #删
    # f=Foo("hi",6)
    # f["age"]=12
    # print(f["age"])
    # f["gao"]=1.77
    
    # print(f["gao"])
    # del f["gao"]         #通过自己实现的(__delitem__方法)
    # del f.gao          #object 原生支持的
    # print(f["gao"])
    View Code

    6,__new__(构造方法:创建一个对象)

    # class A:
    #     def __init__(self):
    #         self.s=5
    #         print("2")
    #     def __new__(cls, *args, **kwargs):
    #         print("1")
    #         return object.__new__(A)
    # a1=A()
    # a2=A()
    # print(a1.s)
    View Code
    # class A:
    #     __instance=False
    #     def __init__(self,name,age):
    #         self.name=name
    #         self.age=age
    #     def __new__(cls, *args, **kwargs):
    #         if cls.__instance:
    #             return cls.__instance
    #         cls.__instance=object.__new__(cls)
    #         return cls.__instance
    # egon=A("egg",45)
    # egon.cloth="棍子"
    # egon.hi="df"
    # print(egon.__dict__)
    # na=A("gh",23)
    # print(na.__dict__)
    # print(egon.__dict__)
    
    
    只会创建一个对象,新的会覆盖旧的对象
    单例模式

    7,__hash__

    # class A:
    #     def __init__(self,name,sex):
    #         self.name=name
    #         self.sex=sex
    #     def __hash__(self):
    #         return hash(self.name+self.sex)
    # a=A("nazha","ni")
    # b=A("nazha","ni")
    # print(hash(a))
    # print(hash(b))
    
    
    有__hash__方法得到的哈希值是参数内容的哈希值。
    没有__hash__方法得到的哈希值是对象的哈希值。
    View Code

    8,__eq__

    class A:
        def __init__(self,name):
            self.name=name
        def __eq__(self, other):
            if self.__dict__ == other.__dict__:
                return True
            else:
                return False
    
    ob1=A("alex")
    oa1=A("alex")
    print(ob1==oa1)
    
    __eq__比较内容是否一致
    View Code

     注:默认比较内存地址

  • 相关阅读:
    Detect Capital
    Maximum Depth of Binary Tree
    Max Consecutive Ones
    Single Number
    Nim Game
    Longest Uncommon Subsequence I
    Average of Levels in Binary Tree
    Next Greater Element I
    Island Perimeter
    Fizz Buzz
  • 原文地址:https://www.cnblogs.com/glf1160/p/8330220.html
Copyright © 2011-2022 走看看