Python 9(反射,异常处理,动态加载模块)

本节内容

  • 反射详解
  • 异常处理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
>
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 
    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("不管有没有错,都执行“)

结果
一切正常
不管有没有错,都执行
  • 常见异常总结
    Python 9(反射,异常处理,动态加载模块)_第1张图片
    Python 9(反射,异常处理,动态加载模块)_第2张图片
    Python 9(反射,异常处理,动态加载模块)_第3张图片

自定义异常

  • 自定义一个异常类
# 自定义异常 不是自动触发的  而是自己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 


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 


duoduo is eating shaomai
duoduo

你可能感兴趣的:(----Python)