• python基础篇18-异常/反射/单例模式


    1.异常

    在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面。

     1 while True:
     2     try:
     3         #逻辑代码块
     4         inp = input("请输入序号")
     5         i = int(inp)
     6 
     7     except Exception as e:
     8         #e是Exception对象,对象中封装了错误信息,Exception接收所有错误;Indexerror只能捕捉指针错误,Valueerror只能捕捉值错误
     9         #Exception和Valueerror等都是Exception的子类;
    10         #上述的代码块如果出错,自动执行当前块的内容;
    11         print(e)
    12         i = 1
    13     print(i)
    14 
    15 # 请输入序号4
    16 # 4
    17 # 请输入序号ee
    18 # invalid literal for int() with base 10: 'ee'
    19 # 1

    异常种类:

    AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
    IOError 输入/输出异常;基本上是无法打开文件
    ImportError 无法引入模块或包;基本上是路径问题或名称错误
    IndentationError 语法错误(的子类) ;代码没有正确对齐
    IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
    KeyError 试图访问字典里不存在的键
    KeyboardInterrupt Ctrl+C被按下
    NameError 使用一个还未被赋予对象的变量
    SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    TypeError 传入对象类型与要求的不符合
    UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
    ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    常用异常
    ArithmeticError
    AssertionError
    AttributeError
    BaseException
    BufferError
    BytesWarning
    DeprecationWarning
    EnvironmentError
    EOFError
    Exception
    FloatingPointError
    FutureWarning
    GeneratorExit
    ImportError
    ImportWarning
    IndentationError
    IndexError
    IOError
    KeyboardInterrupt
    KeyError
    LookupError
    MemoryError
    NameError
    NotImplementedError
    OSError
    OverflowError
    PendingDeprecationWarning
    ReferenceError
    RuntimeError
    RuntimeWarning
    StandardError
    StopIteration
    SyntaxError
    SyntaxWarning
    SystemError
    SystemExit
    TabError
    TypeError
    UnboundLocalError
    UnicodeDecodeError
    UnicodeEncodeError
    UnicodeError
    UnicodeTranslateError
    UnicodeWarning
    UserWarning
    ValueError
    Warning
    ZeroDivisionError
    更多异常
        try:
            li = [11, 22]
            li[1]
            int('w3r')    
    
        except IndexError as e:     #细分的要放在最前面,try中的代码块出错会执行except中的代码
            print('IndexError',e)
        except ValueError as e:
            print('ValueError',e)
        except Exception as e:
            print('Exception',e)
        else:      #try中的代码块不出错就会执行else中的代码
            ret = 1
            print('elese')
        finally:    #最后执行的代码块,不管有没有出错都会执行finally代码块
            print('....')
    实例try-except-finally
    try:
        raise Exception('抛出异常.........')
    except Exception as e:
        print(e)
    
    #抛出异常.........
    实例-主动触发异常
    class lriwuException(Exception):
     
        def __init__(self, msg):
            self.message = msg
     
        def __str__(self):
            return self.message
     
    try:
        raise lriwuException('我的异常')   #通过 lriwuException类创建对象赋值给e
    except lriwuException as e:
        print(e)   #调用e对象的__str__()方法,获取返回值
    
    #我的异常
    实例-自定义异常

     

    断言:用于强制用户满足某条件,不满足就会报错,并且抛出异常。

    1 # assert 条件
    2 try:
    3    # assert 条件
    4  
    5     assert 1 == 1  #条件成立,代码块继续往下执行
    6     print("111")
    7  
    8     assert 1 == 2 
    9     print("222")     #条件若不成立,代码块抛出AssertionError异常

    2.反射

    python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,通过字符串的形式操作对象中的成员:检查是否含有某成员、获取成员、设置成员、删除成员。(一切事物都是对象!!!

     1 class Foo:
     2     def __init__(self, name,age):
     3         self.name = name
     4         self.age = age
     5 
     6     def show(self):
     7         return  "%s-%s " %(self.name,self.age)
     8 
     9 obj = Foo('lriwu', 18)
    10 
    11 
    12 # #### 以字符串的方式获取成员:getattr ####
    13 v=getattr(obj, 'name')
    14 print(v)   #输出:lriwu
    15 
    16 func = getattr(obj,'show')
    17 print(func)   #<bound method Foo.show of <__main__.Foo object at 0x00000168F5FC35F8>>
    18 r = func()
    19 print(r)   #lriwu-18
    20 
    21 # #### 以字符串的方式检查是否含有成员:hasattr ####
    22 print((obj, 'name'))   #检查对象中是否含有name成员  True
    23 print((obj, 'func'))   #检查对象中是否含有func成员  True
    24 
    25 # #### 以字符串的方式设置成员 ####
    26 setattr(obj, 'age', 18)
    27 setattr(obj, 'show', lambda num: num + 1)
    28 
    29 # #### 以字符串的方式删除成员 ####
    30 delattr(obj, 'name')
    31 delattr(obj, 'func')

    类也是一个对象:

     1 class Foo:
     2      stat = '123'
     3      def __init__(self, name,age):
     4          self.name = name
     5          self.age = age
     6 
     7 #通过字符串的形式操作对象中的成员:类也是对象
     8 r = getattr(Foo,'stat')
     9 print(r)
    10 
    11 #123

     详细解析:

    当我们要访问一个对象的成员时,应该是这样操作:

     1 class Foo(object):
     2  
     3     def __init__(self):
     4         self.name = 'alex'
     5  
     6     def func(self):
     7         return 'func'
     8  
     9 obj = Foo()
    10  
    11 # 访问字段
    12 obj.name
    13 # 执行方法
    14 obj.func()

    a、上述访问对象成员的 name 和 func 是什么? 

    答:是变量名

    b、obj.xxx 是什么意思? 

    答:obj.xxx 表示去obj中或类中寻找变量名 xxx,并获取对应内存地址中的内容。

    c、需求:请使用其他方式获取obj对象中的name变量指向内存中的值 “lriwu”

    1 class Foo(object):
    2  
    3     def __init__(self):
    4         self.name = 'lriwu'
    5  
    6 # 不允许使用 obj.name
    7 obj = Foo()

     答:有两种方式,如下:

    方式一:

    class Foo(object):
    
        def __init__(self):
            self.name = 'alex'
    
        def func(self):
            return 'func'
    
    
    obj = Foo()
    
    print obj.__dict__['name']
    View Code

    方式二:

    class Foo(object):
    
        def __init__(self):
            self.name = 'alex'
    
        def func(self):
            return 'func'
    
    
    obj = Foo()
    
    print getattr(obj, 'name')
    View Code

    反射实用例子:

     1 s2.py
     2 def f1():
     3   return '首页'
     4 def f2():
     5   return '新闻'
     6 def f3():
     7   return '视频'
     8 
     9 ##################################
    10 
    11 s1.py
    12 import s2  #模块也是对象
    13 inp = input("请输入要查看的URL")
    14 if hasattr(s2,inp):
    15 func = getattr(s2,inp)
    16 result = func()
    17 print(result)
    18 else:
    19 print('404')
    反射例子

     3.单例设计模式

    单例,顾名思义就是单个实例,即永远使用一个对象。如以下例子:

    class Foo():
        def __init__(self,name,age):
            
            self.name = name
            self.age = age
    
        def show(self):
            
            print(self.name,self.age)
    
    v = none
    
    while True:
        if v:
            v.show()
        else:
            v = Foo('lriwu',19)
            v.show()
    
    #永远使用同一个对象的show()方法

    建议使用以下方式创建单例模式:

    class Foo():
        __v = None
        
        @classmethod
        
        def get_instance(cls):
        
            if cls.__v:
                return cls.__v
            else:
                cls.__v = Foo()
            
                return cls.__v
    
    #这时无需使用类名() 创建对象了
    
    obj1 = Foo.get_instance()    
    print(obj1)                      #<__main__.Foo object at 0x000000E8>
    obj2 = Foo.get_instance()    
    print(obj2)                       #<__main__.Foo object at 0x000000E8>
    
    #obj1和obj2  是同一个对象

     

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

     

     

     

     

     

  • 相关阅读:
    Appium环境配置
    MongoDB_09——执行计划
    mongoDB_08索引的操作
    MongoDB常用命令
    MongoDB_07_复杂查询
    MongoDB_06_分页查询
    docker-ce 安装
    Kubernetes集群搭建 ver1.20.5
    Deploying Portainer CE in Docker
    mysql常用命令
  • 原文地址:https://www.cnblogs.com/lriwu/p/8511636.html
Copyright © 2020-2023  润新知