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  是同一个对象

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2018-03-06 22:17  lriwu  阅读(223)  评论(0编辑  收藏  举报