Python基础5 - 异常处理, 反射, 单例模式
异常处理
异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止). 这种错误有两种, 一为语法错误, 二为逻辑错误
逻辑错误:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#TypeError:int类型不可迭代 for i in 3: pass #ValueError num=input(">>: ") #输入hello int(num) #NameError aaa #IndexError l=['egon','aa'] l[3] #KeyError dic={'name':'egon'} dic['age'] #AttributeError class Foo:pass Foo.x #ZeroDivisionError:无法完成计算 res1=1/0 res2=1+'str'
异常种类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常;基本上是无法打开文件 ImportError 无法引入模块或包;基本上是路径问题或名称错误 IndentationError 语法错误(的子类) ;代码没有正确对齐 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访问字典里不存在的键 KeyboardInterrupt Ctrl+C被按下 NameError 使用一个还未被赋予对象的变量 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了) TypeError 传入对象类型与要求的不符合 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
异常处理:
s1 = 'hello' try: int(s1) except IndexErro as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e)
在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:
s1 = 'hello' try: int(s1) except Exception as e: print(e)
异常结构:
try: # 主代码块 pass except KeyError as e: # 异常时,执行该块 pass else: # 主代码块执行完,执行该块 pass finally: # 无论异常与否,最终执行该块 pass
主动触发异常:
try: raise Exception('错误了...') except Exception as e: print(e)
自定义异常
class MyException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise MyException('我的异常') except MyException as e: print(e)
断言
# assert 条件 assert 1 == 1 assert 1 == 2 #只要条件返回False, 就会触发异常
适用场景: 只有在错误发生的条件无法预知的情况下,才应该加上try...except
反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
python中的反射功能是四个内置函数提供:hasattr、getattr、setattr、delattr,这四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员
class Foo(object): def __init__(self): self.name = 'charon' def func(self): return 'func' obj = Foo() # #### 检查是否含有成员 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 获取成员 #### getattr(obj, 'name') getattr(obj, 'func') # #### 设置成员 #### setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 #### delattr(obj, 'name') delattr(obj, 'func')
反射是通过字符串的形式操作对象相关的成员. 一切事物都是对象
模块是对象, 类也是对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
NAME = 'alan def test(): return 'charon' class Foo: def __init__(self): self.name = 'alan123' #---------------------------- def f1(): return '首页' def f2(): return '精华' def f3(): return '新闻'
import reflectionTest r1 = getattr(reflectionTest, 'NAME') print(r1) #alan r2 = getattr(reflectionTest, 'test') print(r2()) #charon cls = getattr(reflectionTest, 'Foo') print(cls) #<class 'reflectionTest.Foo'> obj = cls() print(obj) #<reflectionTest.Foo object at 0x10402bc18> print(obj.name) #alan123 #------------------------------------ inp = input('>>>输入要查看的URL: ') if hasattr(reflectionTest, inp): result = getattr(reflectionTest, inp) print(result()) else : print(404)
好处:
好处一:实现可插拔机制
可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用. 可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
好处二:动态导入模块(基于反射当前模块成员)
单例模式
单例,顾名思义单个实例 - 使用同一份实例(对象)
连接数据库,每个请求到来,都需要在内存里创建一个实例,再通过该实例执行指定的方法.
如果并发量大的话,内存里就会存在非常多功能上一模一样的对象. 存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用同一个示例
单例模式用来保证内存中仅存在一个实例
单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费
class Foo: __instance = None # @classmethod # def get_instance(cls): # if cls.__instance: # return cls.__instance # # else: # cls.__instance = Foo() # return cls.__instance @staticmethod def get_instance(): if Foo.__instance: return Foo.__instance else: Foo.__instance = Foo() return Foo.__instance #创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.get_instance() obj1 = Foo.get_instance() print(obj1) #<__main__.Foo object at 0x10301ad30> obj2 = Foo.get_instance() print(obj2) #<__main__.Foo object at 0x10301ad30> obj3 = Foo.get_instance() print(obj3) #<__main__.Foo object at 0x10301ad30>
创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.get_instance()
第二种创建单例模式的方法
# 创建单例模式方法一 class Foo(): __instance = None @classmethod def instance(cls): if Foo.__instance: return Foo.__instance else: obj = Foo() Foo.__instance = obj return Foo.__instance obj1 = Foo().instance() obj2 = Foo().instance() print(obj1,obj2) # 创建单例模式方法二 class Boo(): __instance = None def __init__(self): pass def __new__(cls, *args, **kwargs): # __new__在执行__init__之前先执行了 if cls.__instance: return cls.__instance else: obj = object.__new__(cls) cls.__instance = obj return cls.__instance obj11 = Boo() obj22 = Boo() print(obj11,obj22)