zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/huangjm263/p/8329834.html
Copyright © 2011-2022 走看看