异常处理、反射、单例模式
Exception
Python中的异常处理和其他语言是类似的,基本格式如下:
try:
# 代码块,逻辑
inp = input('请输入序号:')
i = int(inp)
except Exception as e:
# e是Exception对象,对象中封装了错误信息
# 上述代码块如果出错,自动执行当前块的内容
print(e)
i = 1
print(i)
不同类型的错误
看如下代码:
def fun():
ret = 0
try:
li = [11, 22]
li[1]
int('w3r')
except IndexError as e:
print('IndexError',e)
except ValueError as e:
print('ValueError',e)
except Exception as e:
print('Exception',e)
# 如果没有出错执行 else下内容
else:
ret = 1
print('elese')
# finally语句块一定会在最后执行
finally:
print('....')
return ret
r = fun()
在Python中主动触发异常用 raise Exception('ERROR!')
,raise实际上和其他语言的throw作用相同。主动抛出异常的作用主要是在记录日志的过程中,可以直接write+错误信息名。
自己定义一个异常
代码如下:
class MyError(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise MyError('MyError...')
except MyError as e:
print(e) # e对象的__str__()方法
assert 断言
assert用来表示程序执行必须要通过的条件,否则就抛出错误,要注意的是这个错误一般不捕获。assert 1 == 2
抛出异常,assert 1 == 1
程序正常运行。
反射
先看一个问题:
class Foo:
def __init__(self, name,age):
self.name = name
self.age = age
def show(self):
return "%s-%s " %(self.name,self.age)
def __int__(self):
return 123
def __str__(self):
return 'uuu'
obj = Foo('alex', 18)
b = 'name'
如果想拿到obj.name
,怎么样通过b来拿呢?一种方法是通过之前提到的__dict__
,直接用obj.__dict__[b]
拿字典中的值就可以了。
getattr()
还有一种方法是用getattr()
函数:
print(getattr(obj, b))
func = getattr(obj, 'show')
print(func())
# hasattr(obj, 'name') 是否有某个属性,返回True或False
# setattr(obj, 'k1', 'v1') 设置新属性
# delattr(obj, 'k1') 删除某属性
上面代码中提到的四种函数都可以通过字符串的形式访问对象中的成员。同时这四种函数不仅可以访问一个对象,也可以访问模块。
单例模式
单例模式从字面上理解就是只实例化一次,每次使用的都是同一个实例,节省内存,节省时间。可以看一个简单的单例模式:
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 0x00000232B3A58828>
obj2 = Foo.get_instance()
print(obj2) # <__main__.Foo object at 0x00000232B3A58828>
obj3 = Foo.get_instance()
print(obj3) # <__main__.Foo object at 0x00000232B3A58828>