python反射之基本认识

283 阅读2分钟

在日常工作中, 我们经常会遇到如下的问题:执行对象中的某个方法或者属性,但是事先无法确定该方法或者属性是否存在。这时需要一个特殊的方法或机制来对这种情形下的属性或者方法进行访问,这种机制就称为反射,有时也叫自省。

先来看一个示例

def add(a, b):
    return a + b
​
​
def sub(a, b):
    return a - b
​
​
def mul(a, b):
    return a * b
​
​
def truediv(a, b):
    return a / b
​
​
def main(sign, a, b):
    if sign == "+":
        result = add(a, b)
    elif sign == "-":
        result = sub(a, b)
    elif sign == "x":
        result = mul(a, b)
    elif sign == "/":
        result = truediv(a, b)
    print(f"{a}{sign}{b}=={result}")
​
​
if __name__ == "__main__":
    main("+", 12, 23)

对于上述这种根据入参不同来调用执行不同的方法,以实现不同的操作是很常见的需求。上述代码是采取了最原始初级的办法进行实现。更进一步的,可以利用反射机制来实现该功能,其代码如下:

class Caculate(object):
    def add(self, a, b):
        return a + b

    def sub(self, a, b):
        return a - b

    def mul(self, a, b):
        return a * b

    def truediv(self, a, b):
        return a / b


def main(sign, a, b):
    cal = Caculate()
    dict1 = {"+": "add", "-": "sub", "*": "mul", "/": "truediv"}
    if hasattr(cal, dict1[sign]):
        func = getattr(cal, dict1[sign])
        result = func(a, b)
        print(f"{a}{sign}{b}={result}")
    else:
        print('没有该方法')


if __name__ == "__main__":
    main("+", 12, 23)

result:

12+23=35

在这个例子中,用户输入的sign是一个字符串(加减乘除的运算符号),通过字典dict1获得value的值为add,然后getattr函数去查找Caculate这个类里去查找叫add的成员,该过程相当于将字符串add转换成add()。然后获取到的结果赋值给func变量。最后调用func函数,实现对add函数的调用。当然,这里的func的具体值根据用户输入的不同而动态变化。

这就是python反射了,其本质是利用字符串的形式去对象中操作成员,一种基于字符串的事件驱动。 另外,为了防止用户的非法输入导致报错,这里先用hasattr函数进行事先判断,判断对象中有无对应成员。