Day18 反射、异常捕获

标签: Python

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执行文件内全局函数

  1. 通过sys找到文件名
  2. 万物皆对象,以文件为类使用 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("条件成立")