• python------面向对象进阶


    一、isinstance和issubclass

    class A:pass
    class B(A):pass
    a = A()
    print(isinstance(a,A))  # True   a是A的对象
    print(issubclass(B,A))  # True    B是A的派生类
    print(issubclass(A,B))  # False
    # isinstance(obj,cls)检查是否obj是否是类 cls 的对象
    # issubclass(sub, super)检查sub类是否是 super 类的派生类
    isinstance和issubclass

    二、反射

    反射:根据字符串的形式去某个对象中操作它的成员
    class Person:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age
        def say(self):
            print('伊娃伊娃哟')
    p1 = Person('jim','',20)
    print(hasattr(p1,'name')) #判断有木有,有则True,没有False
    print(getattr(p1,'sex')) #找不到报错
    print(getattr(p1,'age1',22))  #可以设置返回值则不报错
    
    del p1.name    #删除属性方式一
    print(p1.__dict__)
    delattr(p1,'name')  #删除属性方式二
    print(p1.__dict__)
    
    setattr(p1,'name','lucy')  #设置属性值
    print(p1.__dict__)
    反射函数的用法

     反射的好处:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,它其实就是一种“后期绑定” 。

           可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    class FtpClient:
        'ftp客户端,但是还么有实现具体的功能'
        def __init__(self,addr):
            print('正在连接服务器[%s]'%addr)
            self.addr = addr
    f1 = FtpClient('192.168.1.1')
    if hasattr(f1,'get'):
        func_get = getattr(f1,'get')
        func_get()
    else:
        print('---->不存在此方法')
        print('您可以先处理其它逻辑')
    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')()
    反射类的属性和方法
    #my.py文件
    day = 'Monday'  
    def wahaha():
        print('wahahaha')
    class C:
        pass
    
    #导入my模块
    import my   
    # 反射模块的属性
    print(my.day)   # Monday
    print(getattr(my,'day'))  # Monday
    # 反射模块的方法
    getattr(my,'wahaha')()  # wahahaha
    反射模块的属性和方法
    import time
    print(getattr(time,'time')())  # 1516612064.430534
    print(getattr(time,'asctime')())  # Mon Jan 22 17:07:44 2018
    内置模块也能用发射
    def qqxing():
        print('qqxing')
    year = 2018
    import sys
    # print(sys.modules['__main__'].year)
    # 反射自己模块中的变量
    print(getattr(sys.modules['__main__'],'year'))  # 2018
    # 反射自己模块中的函数
    getattr(sys.modules['__main__'],'qqxing')()  # qqxing
    变量名 = input('>>>')
    print(getattr(sys.modules[__name__],变量名))  # >>>
    发射自己模块中的变量和函数

    __setattr__ 添加/修改属性时会触发它的执行

    __delattr__  删除属性时会触发

    __getattr__  只有在使用点调用属性且属性不存在的时候才会触发

    系统内置函数属性:若你定义了就用你定义的函数属性,不定义就用系统默认的函数属性

    class Foo:
        x = 1
        def __init__(self,y):
            self.y = y
        def __getattr__(self, item):
            print('---->from getattr:你找的属性不存在')
        def __setattr__(self, key, value):
            print('---->from setattr')
            self.__dict__[key] = value
        def __delattr__(self, item):
            print('---->from delattr')
            self.__dict__.pop(item)
    
    # __setattr__添加/修改属性会触发它的执行
    f1 = Foo(10)
    print(f1.__dict__)  # {'y': 10}
    # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,
    # 除非你直接操作属性字典,否则永远无法赋值
    f1.z = 3
    print(f1.__dict__)  # {'y': 10, 'z': 3}
    
    #__delattr__ 删除属性的时候会触发
    f1.__dict__['a'] = 3
    print(f1.__dict__)  # {'z': 3, 'y': 10, 'a': 3}
    del f1.a
    print(f1.__dict__)  # {'z': 3, 'y': 10}
    
    #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
    f1.xxxx   #---->from getattr:你找的属性不存在
    __setattr__、__delattr__、__getattr__

     三、 __str__ 和 __repr__

    改变对象的字符串显示__str__, __repr__

    自定制格式字符串__format__

    # 双下方法
    # 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'
    nvshen = Teacher('女神',250)
    print(nvshen)  # 打印一个对象的时候,就是调用a.__str__
    print(repr(nvshen))
    print('>>> %r'%nvshen)
    #a.__str__ --> object
    # object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址
    
    # %s str()  直接打印 实际上都是走的__str__
    # %r repr()  实际上都是走的__repr__
    # repr 是str的备胎,但str不能做repr的备胎
    
    # print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串
    # 如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。
    # repr(),只会找__repr__,如果没有找父类的
    __str__和__repr__
    class B:
        def __str__(self):
            return 'str : class B'
        def __repr__(self):
            return 'repr : class B'
    b = B()
    print('%s' % b)  # str : class B
    print('%r' % b)  # repr : class B
    %s和%r

    四、 __del__

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

    class A:
        def __del__(self):   # 析构函数: 在删除一个对象之前进行一些收尾工作
            print('执行我啦')
            self.f.close()
    a = A()
    a.f = open('my.py')   # 打开文件 第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中
    del a          # a.f 拿到了文件操作符消失在了内存中
    # del a   # del 既执行了这个方法,又删除了变量
    # 引用计数
    __del__
    class Foo:
        def __del__(self):
            print('执行我啦')
    f1 = Foo()
    del f1
    print('------->')
    
    #输出结果
    '''
    执行我啦
    ------->
    '''
    View Code

    五、 __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])
    a = A('jim')()
    __call__

    六、item系列(__getitem__,__setitem__,__delitem__)

    class Foo:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        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('egon',38,'')
    print(f['name'])
    f['hobby'] = ''
    print(f.hobby,f['hobby'])
    # del f.hobby      # object 原生支持  __delattr__
    del f['hobby']   # 通过自己实现的
    print(f.__dict__)
    item系列

    七、__new__ 

    构造方法 : 创建一个对象

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)
    
    a1 = A()
    #结果
    # in new function
    # in init function
    a2 = A()
    #结果
    # in new function
    # in init function
    a3 = A()
    #结果
    # in new function
    # in init function
    print(a1)   #<__main__.A object at 0x0000014CC7673B70>
    print(a2)   #<__main__.A object at 0x0000014CC7673BA8>
    print(a3)   #<__main__.A object at 0x0000014CC7673C18>
    print(a1.x)  # 1
    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
    
    jim = A('jim',38)
    jim.cloth = '小花袄'
    lucy = A('lucy',25)
    print(lucy)  # <__main__.A object at 0x000002A579843BE0>
    print(jim)   # <__main__.A object at 0x000002A579843BE0>
    print(lucy.name)  # lucy
    print(jim.name)   # lucy
    print(lucy.cloth)  # 小花袄
    单例模式

    八、__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('jim')
    ob2 = A('jim')
    ob3 = A('jim1')
    print(ob1 == ob2)   # True
    print(ob1 == ob3)   # False
    View Code

    九、__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('jim','')
    b = A('jim','nv')
    print(hash(a))  # -4536380992615375499
    print(hash(b))  # -4536380992615375499
    View Code

    十、__len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))   # 2
    View Code
  • 相关阅读:
    JVM heap中各generation的大小(Sizing the Generations)
    MySQL中分组取第一条, 以及删除多余的重复记录
    八芯网线水晶头做法(线序)
    Win7命令行下查看无线网络信息
    OpenWrt的开机启动服务(init scripts)
    犀牛书的实例代码:给对象添加freeze, hide, 查询descriptors
    ES6新特性:Javascript中Generator(生成器)
    ES6新特性:Function函数扩展, 扩展到看不懂
    ES6新特性:Javascript中的Map和WeakMap对象
    ES6新特性:Javascript中Set和WeakSet类型的数据结构
  • 原文地址:https://www.cnblogs.com/huangjm263/p/8329834.html
Copyright © 2020-2023  润新知