zoukankan      html  css  js  c++  java
  • 面向对象进阶-反射,内置方法

    isinstance和issubclass

    isinstance(obj,cls)判断对象所属类型,包括继承关系,     检查obj是不是cls的对象(传两个参数,一个是对象,一个是类)

    # class A:pass
    # class B(A):pass
    # b = B()
    # print(isinstance(b,B)) #o,t
    # print(isinstance(b,A)) #o,t
    # l = list()
    # print(l)  # type(l)
    # class mystr(str):pass
    # ms = mystr('alex')
    # print(ms)
    # print(type(ms) is str)  # 不包含继承关系,只管一层
    # print(isinstance('alex',str)) # 包含所有的继承关系

    issubclass(sub, super)判断类与类之间的继承关系, 检查sub是不是super的子类(传两个参数,一个是子类,一个是父类)

    # class A:pass
    # class B(A):pass
    # print(issubclass(B,A))
    # print(issubclass(A,B))

    反射

    反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用反射。

    反射有四种方法:

    hasattr:hasattr(object,name)判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

    getattr:获取对象的属性或者方法,如果存在则打印出来。hasattr和getattr配套使用

        需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

    setattr:给对象的属性赋值,若属性不存在,先创建后赋值

    delattr:删除该对象指定的一个属性

     1.类  静态属性 类方法 静态方法的反射

    # 命名空间.XXX == getattr(命名空间,'XXX')
    # class Student:
    #     ROLE = 'STUDENT'
    #     @classmethod
    #     def check_course(cls):
    #         print('查看课程了')
    #
    #     @staticmethod
    #     def login():
    #         print('登录')
    # # 反射查看属性
    # # print(Student.ROLE)
    # # print(getattr(Student,'ROLE'))
    #
    # # 反射调用方法
    # # getattr(Student,'check_course')()  # 类方法
    # # getattr(Student,'login')()         # 静态方法
    #
    # num = input('>>>')
    # if hasattr(Student,num):
    #     getattr(Student,num)()
    View Code

    2.对象 对象属性  方法 的反射

    # class A():
    #     def __init__(self,name):
    #         self.name = name
    #
    #     def func(self):
    #         print('in func')
    #
    # a = A('alex')
    # print(a.name)
    # print(getattr(a,'name'))
    # getattr(a,'func')()
    View Code

    3. 模块的反射

    # import os   # 别人写好的python代码的结合
    # # os.rename('__init__.py','init')
    # # getattr(os,'rename')('init','__init__.py') # == os.rename
    # rename = os.rename
    # rename2 = getattr(os,'rename')
    # rename2('__init__.py','init')  # os.rename('__init__.py','init')
    # rename('init','init2')          # os.rename('init','init2')
    View Code

    4.反射自己模块中的内容

    # def wahaha():
    #     print('wahaha')
    #
    # def qqxing():
    #     print('qqxing')
    
    #
    # wahaha()
    # qqxing()
    
    # 反射自己模块中的内容  找到自己当前文件所在的命名空间
    # import sys
    # print(sys.modules)
    # import 都相当于导入了一个模块
    # 模块哪个导入了 哪个没导入 在我的python解释器里应该记录下来
    # import sys 是一个模块,这个模块里的所有的方法都是和python解释器相关的
    # sys.modules 这个方法 表示所有在当前这个python程序中导入的模块
    # '__main__': <module '__main__' from 'D:/sylar/python_workspace/day20/4.反射.py'>
    # print(sys.modules['__main__'])
    # my_file = sys.modules['__main__']
    # my_file.wahaha()
    # my_file.qqxing()
    # # 'qqxing'
    # # 'wahaha'
    # getattr(my_file,'wahaha')()
    # getattr(my_file,'qqxing')()
    View Code

     

    内置方法

    __call__

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

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

    # class A:
    #     def __call__(self, *args, **kwargs):
    #         print('执行call方法了')
    #     def call(self):
    #         print('执行call方法了')
    # class B:
    #     def __init__(self,cls):
    #         print('在实例化A之前做一些事情')
    #         self.a = cls()
    #         self.a()
    #         print('在实例化A之后做一些事情')
    # a = A()
    # a()  # 对象() == 相当于调用__call__方法
    # a.call()
    
    # A()() # 类名()() ,相当于先实例化得到一个对象,再对对象(),==>和上面的结果一样,相当于调用__call__方法
    # B(A)
    View Code

    __len__

    # len(dict)
    # len(tuple) str list set
    # class mylist:
    #     def __init__(self):
    #         self.lst = [1,2,3,4,5,6]
    #         self.name = 'alex'
    #         self.age = 83
    #     def __len__(self):
    #         print('执行__len__了')
    #         return len(self.__dict__)
    #
    # l = mylist()
    # print(len(l))
    # len(obj)相当于调用了这个obj的__len__方法
    # __len__方法return的值就是len函数的返回值
    # 如果一个obj对象没有__len__方法,那么len函数会报错
    View Code

    __new__    (构造方法和单例模式)

    # __new__    # ==> 构造方法
    # __init__  # ==> 初始化方法
    
    # class Single:
        # def __new__(cls, *args, **kwargs):
        #     # print('在new方法里')
        #     obj = object.__new__(cls)
        #     print('在new方法里',obj)
        #     return obj
    
        # def __init__(self):
        #     print('在init方法里',self)
    
    # 1.开辟一个空间,属于对象的
    # 2.把对象的空间传给self,执行init
    # 3.将这个对象的空间返回给调用者
    # obj = Single()
    # single的new,single没有,只能调用object的new方法
    # new方法在什么时候执行???
        # 在实例化之后,__init__之前先执行new来创建一块空间
    
    
    # 单例
    # 如果一个类 从头到尾只能有一个实例,说明从头到尾之开辟了一块儿属于对象的空间,那么这个类就是一个单例类
    
    # 单例类
    class Single:
        __ISINCTANCE = None
        def __new__(cls, *args, **kwargs):
            if not cls.__ISINCTANCE:
                cls.__ISINCTANCE = object.__new__(cls)
            return cls.__ISINCTANCE
        def __init__(self,name,age):
            # self.name = name
            # self.age = age
            print(self)
    
    s1 = Single('alex',83)
    s2 = Single('taibai',40)
    # print(s1.name)
    # print(s2.name)
    # print(s1,s2)
    View Code

    __str__

    # __str__
    # l = [1,2,3]  # 实例化一个list的对象
    # # l是个对象
    # print(l)
    
    # class Student:
    #     def __str__(self):
    #         return '%s %s %s'%(self.school,self.cls,self.name)
    #
    #     def __init__(self,name,stu_cls):
    #         self.school = 'oldboy'
    #         self.name = name
    #         self.cls = stu_cls
    #
    # he = Student('hezewei','py14')
    # # print(he)
    # huang = Student('huangdongyang','py14')
    # # print(huang)
    # # print(str(he))   # 内置的数据类型,内置的类,相当于执行__str__
    # print('学生1 : %s'%he)
    
    # print一个对象相当于调用一个对象的__str__方法
    # str(obj),相当于执行obj.__str__方法
    # '%s'%obj,相当于执行obj.__str__方法
    View Code

    __repr__

    是__str__的备胎.如果有__str__方法,那么# print %s str都先去执行__str__方法,并且使用__str__的返回值
    如果没有__str__,那么 print %s str都会执行repr
    repr(obj),%r

    # 在子类中使用__str__,先找子类的__str__,没有的话要向上找,只要父类不是object,就执行父类的__str__
    # 但是如果出了object之外的父类都没有__str__方法,就执行子类的__repr__方法,如果子类也没有,
    # 还要向上继续找父类中的__repr__方法.
    # 一直找不到 再执行object类中的__str__方法
    
    # a = '123'
    # print(a)
    # print(repr(a))
    
    # class A:
    #     def __init__(self,name):
    #         self.name = name
    #     def __str__(self):
    #         return '**%s**'%self.name
    #     def __repr__(self):
    #         return self.name
    #
    # class B(A):
    #     def __init__(self,name):
    #         self.name = name
    #     def __repr__(self):
    #         return '***'
    #
    # a = B('alex')
    # print(a)
    # print(str(a),repr(a))
    # print('%s | %r'%(a,a))
    
    # print('---%r---'%('abc'))
    # print('---%s---'%('abc'))
    
    # __str__ __repr__ : repr
    View Code

     __del__

    析构方法,释放一个空间之前执行

    # 构造方法  申请一个空间
    # 析构方法  释放一个空间之前执行
    # 某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源  网络资源
    
    
    # 垃圾回收机制
    # class A:
    #     def __del__(self):
    #         # 析构方法 del A的对象 会自动触发这个方法
    #         print('执行我了')
    # a = A()
    # del a  # 对象的删除 del
    # print(a)
    
    # class File():
    #     # 处理文件的
    #     def __init__(self,file_path):
    #         self.f = open(file_path)
    #         self.name = 'alex'
    #
    #     def read(self):
    #         self.f.read(1024)
    #
    #     def __del__(self):   # 是去归还/释放一些在创建对象的时候借用的一些资源
    #         # del 对象的时候   程序员触发
    #         # python解释器的垃圾回收机制 回收这个对象所占得内存的时候  python自动触发的
    #         self.f.close()
    # f = File('文件名')
    # f.read()
    # 不管是主动还是被动,这个f对象总会被清理掉,被清理掉就触发__del__方法,触发这个方法就会归还操作系统的文件资源
    
    # python解释器在内部就能搞定的事儿
    # 申请一块儿空间 操作系统分配给你的
    # 在这一块儿空间之内的所有事儿 归你的python解释器来管理
    # a = 1
    # del a
    # 对象 --> 内存
    
    # f = open('wenjian')  # python --> 操作系统 --> 硬盘里的文件 --> 文件操作符
    # f.close()
    # # 文件操作符
    # del f
    View Code

    item系列

    __getitem__\__setitem__\__delitem__

    # item系列 和对象使用[]访问值有联系
    # obj = {'k':'v'}
    # print(obj)   # 字典的对象
    # print(obj['k'])
    
    # 在内置的模块中,
    # 有一些特殊的方法,要求对象必须实现__getitem__/__setitem__才能使用
    # class B:
    #     def __getitem__(self, item):
    #         return getattr(self,item)
    #     def __setitem__(self, key, value):
    #         setattr(self,key,value*2)
    #     def __delitem__(self, key):
    #         delattr(self,key)
    # b = B()
    # # b.k2 = 'v2'
    # # print(b.k2)
    # b['k1'] = 'v1'  # __setitem__
    # print(b['k1'])  # __getitem__
    # del b['k1']     # __delitem__
    # print(b['k1'])
    
    # class B:
    #     def __init__(self,lst):
    #         self.lst = lst
    #     def __getitem__(self, item):
    #         return self.lst[item]
    #     def __setitem__(self, key, value):
    #         self.lst[key] = value
    #     def __delitem__(self, key):
    #         self.lst.pop(key)
    # b = B(['111','222','ccc','ddd'])
    # print(b.lst[0])
    # print(b[0])
    # b[3] = 'alex'
    # print(b.lst)
    # del b[2]
    # print(b.lst)
    
    
    # 类
    # 每一个对象都是一副扑克牌
    # 我想查看这个对象 来查看整副牌
    
    # 我想从这一副牌中随机抽一张牌
    # 我想完成打乱这副牌的顺序的功能
    View Code

    __hash__

    # hash方法
    # 底层数据结构基于hash值寻址的优化操作
    # hash是一个算法
    # 能够把某一个要存在内存里的值通过一系列计算,
    # 保证不同值的hash结果是不一样的
    # '127647862861596'  ==> 927189778748
    # 对同一个值在多次执行python代码的时候hash值是不同
    # 但是对同一个值 在同一次执行python代码的时候hash值永远不变
    # print(hash('abc'))  # 6048279107854451739
    # print(hash('abc'))
    # print(hash('abc'))
    # print(hash('abc'))
    # print(hash('abc'))
    # print(hash('abc'))
    
    # 字典的寻址  - hash算法
    # d = {'key':'value'}
    # hash - 内置函数
    
    # set集合
    # se = {1,2,2,3,4,5,'a','b','d','f'}
    # print(se)
    
    # d = {'key':'v1','key':'v2'}
    # print(d['key'])
    
    # hash(obj) #obj内部必须实现了__hash__方法
    View Code

    __eq__

    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __eq__(self, other):
            if self.name == other.name and self.age == other.age:
                return True
    a = A('alex',83)
    aa = A('alex',83)
    aa2 = A('alex',83)
    aa3 = A('alex',83)
    aa4 = A('alex',83)
    aa5 = A('alex',83)
    aa6 = A('alex',83)
    print(a,aa)
    print(aa3 == aa == aa4)  # ==这个语法 是完全和__eq__
    View Code

     

    幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。
  • 相关阅读:
    致歉
    [公告]博客园正在对网站程序进行性能优化
    [公告]调整默认发布选项
    网站情况继续汇报
    定制“Server Too Busy”错误信息
    可恶的垃圾广告
    博客园分站服务器故障
    很值得期待—SharePoint "V3.0"新特性
    安装Vistual Studio 2005的小问题
    安装智能陈桥五笔时请小心
  • 原文地址:https://www.cnblogs.com/TodayWind/p/13915064.html
Copyright © 2011-2022 走看看