• Python 抽象篇:面向对象之高阶用法


    1.检查继承

    如果想要查看一个类是否是另一个类的子类,可以使用内建的issubclass函数

    如果想知道已知类的基类,可以直接使用特殊特性__bases__

    同时,使用isinstance方法检查一个对象是否是一个类的实例(instance)

    如果想知道一个对象属于哪个类,可以使用__class__特性

    2.反射

    python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

    class Foo:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def show(self):
            return "%s-%s"%(self.name,self.age)
    
    obj=Foo('greg',18)
    print(obj.name) #greg
    b="name"
    print(obj.__dict__) #{'name': 'greg', 'age': 18}
    print(obj.__dict__['name'])#greg
    print(obj.__dict__[b])#greg
    
    
    inp=input('>>>')
    #去什么东西里面获取什么内容
    v=getattr(obj,inp)
    print(v)
    
    #反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!! sho
    =getattr(obj,'show') print(sho)#<bound method Foo.show of <__main__.Foo object at 0x000001E00C46CA58>> sh=sho() print(sh)#alex-18 print(hasattr(obj,'name'))#True print(hasattr(obj,'name1'))#False setattr(obj,'k1','v1') print(obj.k1) #v1 #obj.name print(delattr(obj,'name')) #NONE # obj.name

    三种方式获取obj对象中的name变量指向内存中的值 “gregory”

    class Foo(object):
        def __init__(self):
            self.name = 'gregory'
    
    # 不允许使用 obj.name
    obj = Foo()
    print(obj.name)
    print(obj.__dict__['name'])
    print(getattr(obj, 'name'))

    3.对象的嵌套

    class F1:
        def __init__(self):
            self.name="greg"
    class F2:
        def __init__(self,a): #a=f1=[name=greg]
            self.age=a
    class F3:
        def __init__(self,b):#b=f2=[age=name=greg]
            self.dd=b
    
    f1=F1()#[name=greg]
    f2=F2(f1)#[age=name=greg]
    f3=F3(f2)#[dd=[age=name=greg]]
    # print(f3.dd) #<__main__.F2 object at 0x00000232ACA612B0>
    # print(f3.dd.age) #18
    print(f3.dd.age.name) #greg

    4.异常(exception object)

    4.1一些重要的内建异常

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    4.2 捕捉异常
    try:
        li=[11,22]
        li[999] #能捕获错误
        # int('d3de')#不能捕获错误
    except IndexError as e:
        print('IndexError',e)
    except ValueError as e:
        print('ValueError',e)
    except Exception as e: #在python的异常中,有一个万能异常:Exception,他可以捕获任意异常
        print('Exception',e)
    else:
        print('else')
    finally: #finally语句不管try是否发生异常,都会被执行。
        print('……')

    4.3 主动触发异常

    try:
        #主动触发异常
        raise Exception('不过了……')
    except Exception as e:
        print(e)

    raise语句引发了一个没有任何有关错误的普通异常。

    4.4 捕捉异常写到日志

    def db():
        # return True
        return False
    def index():
        try:
            r=input(">>")
            int(r)
            result=db()
            if not result:
                raise Exception('数据库处理错误')
        except Exception as e:
            str_error=str(e)
            print(str_error)
            #打开文件,写错误记录日志
            r=open('log','a')
            r.write(str_error)
    index()

    4.5 自定义异常

    class Gregerror(Exception):
        def __init__(self,msg):
            self.message=msg
        def __str__(self):
            return self.message
    
    # obj=Gregerror('xxx')
    # print(obj)
    
    try:
        raise Gregerror("我错了……")
    except Gregerror as e:
        print(e) #e对象的__str__方法,获取返回值

    4.6 断言

    #assert条件
    print(123)
    assert 1==2#断言
    print(456)

    4.7单例模式

    单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费。

    对于Python单例模式,创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.get_instance() 。实例如下:

    class Foo:
        __v=None
    
        @classmethod
        def get_instance(cls):
            if cls.__v:#如果它有值
                return cls.__v
            else:
                cls.__v=Foo()
                return cls.__v
    #不要再使用 类()
    obj=Foo.get_instance() #obj=创建的对象
    print(obj)
    
    obj2=Foo.get_instance()
    print(obj2)
    
    obj3=Foo.get_instance()
    print(obj3)
    
    # <__main__.Foo object at 0x000001B5A30E10F0>
    # <__main__.Foo object at 0x000001B5A30E10F0>
    # <__main__.Foo object at 0x000001B5A30E10F0>
  • 相关阅读:
    VS Code的使用
    跨平台C++ IDE
    windows CMakeLists.txt
    Windows引用opencv静态库
    【wpf】WPF程序处理多线程的两种方式
    【c#】System.Reflection.TargetInvocationException 调用的目标发生了异常/System.Threading.ThreadAbortException:正在中止线程
    【WinForm】Dev ProgressBarControl 使用汇总
    【WPF】UserControl用户控件怎么添加到Window窗体中
    【WPF】WPF无边框、窗体初始化位置与可拖拽窗体的解决方案
    【c#】未加载mscorlib.pdb/System.Reflection.TargetParameterCountException 未经处理的异常在mscorlib.dll中发生/参数计数不匹配
  • 原文地址:https://www.cnblogs.com/ningxin18/p/7781412.html
Copyright © 2020-2023  润新知