Day18 反射、异常捕获
Day18 反射、异常捕获
1. 反射 - 内部
反射就是通过字符串操作对象中的属性,Python中一切皆对象。 - hasattr() - getattr() - setattr() - delattr()
1.1__getattr__
当对象空间中没有属性时执行,防止报错
class A():
def __init__(self,name):
self.name = name
def __getattr__(self, item):
# 当对象空间中有属性时不执行这个方法,没有属性时才执行
return "没有当前值"
a = A("Alex")
print(a.age) # 没有当前值
1.2__setattr__
当对象空间中没有属性时执行
class A():
def __init__(self,name):
self.name = name # 走 __setattr__
def __setattr__(self, key, value):
# 当对象空间中设置新属性时执行
print("设置值的时候走我!")
self.__dict__[key] = value # 这一行是关键
a = A("Alex") # 设置值的时候走我!
a.age = 20 # 设置值的时候走我!
1.3__delattr__
删除对象空间中属性时执行
class A():
def __init__(self,name):
self.name = name
def __delattr__(self, item):
# 删除对象空间中属性时执行
print("删除值的时候走我!")
self.__dict__.pop(item) # 这一行是关键
a = A("Alex")
del a.name # 删除值的时候走我!
2. 反射 - 外部
2.1 getattr()
getattr(__obj, name, __default)
class A():
def __init__(self, name):
self.name = name
def func(self):
print("is func")
a = A("Alex")
b = input("请输入您要执行的函数") # b = func
getattr(a,b)()
改进一下,防止报错
class A():
def __init__(self, name):
self.name = name
def __getattr__(self, item):
return "Do not have this value"
def func(self):
print("is func")
a = A("Alex")
b = input("请输入您要执行的函数") # b = func
if getattr(a,b) == "Do not have this value":
print("Do not have this function")
else:
getattr(a,b)()
or
class A():
def __init__(self, name):
self.name = name
def func(self):
print("is func")
a = A("Alex")
b = input("请输入您要执行的函数") # b = func
print(getattr(a,b, "真的没有值")) # 没有值返回文字
2.2 hasattr()
hasattr(__obj, __name) 判断属性是否存在,返回布尔值
用hasattr达成上面代码的功效
class A():
def __init__(self, name):
self.name = name
def func(self):
print("is func")
a = A("Alex")
b = input("请输入您要执行的函数") # b = func
if hasattr(a,b): # 判断属性是否存在,返回布尔值
getattr(a,b)()
else:
print("Do not have this function")
2.3 setattr()
setattr(__obj, __name, __value)
class A():
def __init__(self, name):
self.name = name
def func(self):
print("is func")
a = A("Alex")
for i in range(3):
msg = input("请输入您要封装的属性和值,格式如下[age|18]")
k, v = msg.split("|")
setattr(a ,k ,v)
print(a.__dict__)
2.4 delattr()
delattr(__obj, __name)
class A():
def __init__(self, name):
self.name = name
def func(self):
print("is func")
a = A("Alex")
delattr(a, "name")
print(a.name) # 报错
2.5 总结
- hasattr(对象名, 字符串格式属性名) 判断属性在对象是否存在
- getattr(对象名, 要获取的字符串格式属性名, 找不到时返回的提示句)
- setattr(对象名, 要设置的字符串格式属性名, 要设置的值)
- delattr(对象名, 要删除的字符串格式属性名)
2.6 通过str执行文件内全局函数
- 通过sys找到文件名
- 万物皆对象,以文件为类使用 getattr() 执行
import sys
def foo():
print("is foo")
msg = input("input func\n>>>")
obj = sys.modules[__name__]
if hasattr(obj,msg):
getattr(obj, msg)()
else:
print("Not in",obj)
3. 异常处理
异常:错误,错误导致程序不能正常运行。 异常分两种: - 语法错误:print( if - 逻辑错误:int("q")
异常处理:发现错误,及时制止,使程序继续运行。
if True:
try:
print(int("q")) # 尝试运行这段代码
except ValueError:
print("Get Error")
print(123)
异常处理的两种方式: - 流程控制语句 - 异常处理 - “私人定制”
3.1 异常的分类
- AttributeError > 试图访问一个对象没有的属性,例如f.x但是f没有属性x
- ImportError > 无法引入模块或包;基本上是路径问题或名称错误
- IndentationError > 代码没有正确对齐
- IndexError > 下标索引超出序列索引边界
- KeyError > 试图访问字典里不存在的键
- NameError > 使用一个还未被赋予对象的变量
- SyntaxError > Python遇到非法代码,代码不能编译
- TypeError > 传入对象类型与要求的不符合
- UnboundLocalError > 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量
- ValueError > 传入一个调用者不期望的值,即使值的类型是正确的
3.2 基本语法
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
try:
print(int("q"))
except ValueError as e: # e 为捕获的错误信息
print(e)
3.3 万能异常 Exception
try:
print(int("q"))
except Exception as e:
print(e)
3.4 多分支异常
try:
dic["name"]
except ValueError :
print(1)
except KeyError :
print(2)
except NameError :
print(3)
except Exception :
print(4)
else:
print(666) # 没有异常走else
finally:
print(5) # 不管有没有异常都走,一般做善后工作
3.5 主动触发异常
try:
raise TypeError("类型错误")
except Exception as e:
print(e)
3.6 自定义异常
class MeetError(BaseException):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return "lalala"
try:
raise MeetError("类型错误")
except MeetError as e:
print(e)
3.7 断言 assert
assert 1 == 1 # 无事发生
assert 1 == 2 # 直接报错
try:
assert 1 == 2
except: AssertionError:
print("条件不成立")
else:
print("条件成立")