本节内容
- 反射详解
- 异常处理Try-Except
- 动态加载模块
反射
-
通过字符串映射或修改程序运行时的状态,属性,方法,有以下四个方法:
-
getattr (obj, name_str, default =None) 根据字符串去获取obj对象里的对应方法的内存地址
-
hasattr (obj, name_str) 判断一个对象obj里是否有对应的name_str
-
setattr (x, y, v)----x.y = v 通过字符串设置新的属性
-
delattr (x, y) 删除一个属性
-
例1 用到前两个函数
class Dog(object):
def __init__(self, name):
self.name = name
def talk(self):
print("%s is talking..." %self.name)
d = Dog("duoduo")
choice = input(">>:").strip()
print(hasattr(d,choice)) # 判断属性是否在类中
print(getattr(d, choice)) # 得到talk方法
getattr(d,choice)() #调用talk方法
'''实际应用 一般会这样写:
if hasattr(d,choice):
func = getattr(d, choice)
func() # 考虑到可能会再传一些参数进去
'''
结果
>>:talk
True
<bound method Dog.talk of <__main__.Dog object at 0x00000208BFC40048>>
duoduo is talking...
- 例2 加setattr方法
def walk(self):
print("%s is walking ..." %self.name)
class Dog(object):
xxxxxx
if hasattr(d, choice):
func = getattr(d, choice)
func()
else:
setattr(d,choice,walk) #将属性动态设置进去
d.walk(d) #调用时传入self 因为是外部方法
结果
>>:walk
duoduo is walking ...
- 例3
if hasattr(d, choice):
delattr(d,choice) # 删除某个属性
XXX
print(d.name)
结果
>>:name
Traceback (most recent call last):
File "E:/1 python/test python/day7/fanshe.py", line 31, in <module>
print(d.name)
AttributeError: 'Dog' object has no attribute 'name'
异常处理tryExcept
- 为什么需要异常处理机制,因为不希望用户直接看到错误,所以最好是捕捉到错误记录到后台。
- 例1 原始方式
names = [1,2]
data = {}
try:
names[3]
data['name']
except KeyError as e :
print("No this key-----",e)
except IndexError as e:
print("列表操作错误",e)
结果
列表操作错误 list index out of range
- 例2 可预测的错误集合起来
下面这种同时抓多个错误,将错误统一的情形不建议使用,容易分不清哪块出错:
names = [1,2]
data = {}
try:
names[3]
data['name']
except (KeyError,IndexError) as e :
print("错误是:",e)
结果
错误是: list index out of range
- 例3 抓所有错误
也可以抓住所有错误,全部集合为 except Exception as e: print("出错了",e)
但也不建议使用 因为也无法判断错误是哪块出现
- 例4 较为建议的方式
在正常可预测的错误后 + 捕捉所有未知错误(Exception)
try:
open("duodui.txt")
names[3]
data['name']
except (KeyError,IndexError) as e :
print("错误是:",e)
except Exception as e:
print("未知错误",e)
结果
未知错误 [Errno 2] No such file or directory: 'duodui.txt'
- 例5 else一切正常的提示 finally 不管有没有错误都会执行
try:
a = 1
a+=1
except (KeyError,IndexError) as e :
print("错误是:",e)
except Exception as e:
print("未知错误",e)
else:
print("一切正常")
finally:
print("不管有没有错,都执行“)
结果
一切正常
不管有没有错,都执行
- 常见异常总结
自定义异常
- 自定义一个异常类
# 自定义异常 不是自动触发的 而是自己raise的
class DuoException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
raise DuoException("my exception")
except DuoException as e:
print(e)
结果
my exception
动态加载模块
- 实例
文件 day7.classF
class Dog(object):
name = "maomao"
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating shaomai" %(self.name))
return self.name
动态加载
mod = __import__("day7.classF")
print(mod)
instance = getattr(mod.classF,"Dog")
obj = instance("duodo")
obj.eat()
print(obj.name)
结果
init is finished
hello dd
<class 'type'>
<module 'day7' from 'E:\\1 python\\test python\\day7\\__init__.py'>
duodo is eating shaomai
duodo
- 上面方法不建议使用 因为是Python解释器的内置函数
- 官方建议方法:
import importlib
lib = importlib.import_module("day7.classF")
print(lib)
instance = lib.Dog("duoduo")
print(instance.eat())
结果
init is finished
hello dd
<class 'type'>
<module 'day7.classF' from 'E:\\1 python\\test python\\day7\\classF.py'>
duoduo is eating shaomai
duoduo