定义:

        通过字符串的形式去操作对象(类,实例对象,模块中的对象)中的成员(增删改查)叫反射。


一、类实例对象

class Foo:
    tests = 'test'
    def __init__(self,name,age):
            self.name = name
            self.age = age
    def show(self):
            return "%s - %s" %(self.name,self.age)
            
obj = Foo("san",18)

对于以上Foo类实例化出对象obj,在以往我们操作obj中的对象时

print(obj.name)

n = "name"

print(obj.__dict__["name"])

print(obj.__dict__[n])

来获取 ojb.name字段

下面用反射来对类实例化对象obj中的字段进行操作

#getattr   获取字段内容

while True:
    inp = input(">>>")           #输入要获取的字段对象名
    if hasattr(obj,inp):         #判断字段是否存在
        v = getattr(obj,inp)     
        if callable(v):          #判断是否可调用
            print(v())
        else:
            print(v)
    else:
        print("%s 不存在" %inp)

运行结果:

python反射_第1张图片

当输入对象是首先通过hasattr来检查所输入的字段对象是否存在,存在时则打印,不存在给出提示,输入show时,由于show是Foo中的方法,所以被调用,打印出san - 18


#setattr  向对象中赋值字段

class Foo:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
setattr(obj,'sex',"男")   #放在obj对象内存中  
print(obj.sex)

python反射_第2张图片

以上操作等同于obj.sex = "男",往对象中添加字段

同理能添加就能删除

##delattr
# delattr(obj,"name")
# print(obj.name)

这个请自行测试吧

以上是通过类的反射操作对象的字段或方法,下面来说下模块文件中反射


二、模块中反射应用

假设fs2.py中都是网站的功能f1,f2,f3等,通过反射获取并返回值,不存在返回404

这就是python web框架的路由的模拟。

模块文件fs2.py

NAME = "san"
def func():
    return 'func'

class Foo:
    def __init__(self):
        self.name = 123

def f1():
    return "首页"
def f2():
    return "新闻"
def f3():
    return "精华"

bin.py内容

import fs2
r1 = fs2.NAME
r2 = fs2.func()
print(r1,r2)
r1 = getattr(fs2,"NAME")
print(r1)
r2 = getattr(fs2,'func')
print(r2)
print(r2())
cls = getattr(fs2,'Foo')     ##模块中获取类
print(cls)
obj = cls()
print(obj)
print(obj.name)
inp = input("请输入要查看的url:")

if hasattr(fs2,inp):
    func = getattr(fs2,inp)
    result = func()
    print(result)
else:
    print(404)

运行结果:

python反射_第3张图片

以上完整的模拟了从模块中文件获取全已有变量,函数,类。