反射定义:用字符串数据类型的名字,来操作这个名字对应的函数/实例变量/绑定方法/各种方法。(有了一个name的字符串的数据类型,就能拿到这个name变量对应的值)
使用情况:明知道一个变量的字符串数据类型的名字,想直接调用它,但是调不到。
#对象名.属性名==》getattr(对象名,“属性名”)
使用场景(每个都非常重要):
1.反射对象的实例变量
2.反射类的 静态变量/绑定方法/其他方法
3.模块中的所有变量
(1)被导入的模块 --模块
import a #a.py中提前定义了sex变量
a.sex #引用a中的sex变量
(2)当前执行的py文件 --脚本
sex=None
print(sex) #直接打印sex变量
程序举例.
class Person:
def __init__(self,name,age):
Role="治疗"
self.name=name
self.age=age
def qqxing(self):
print("qqxing")
return 666
alex=Person("alex",83)
wusir=Person("wusir",73)
ret=getattr(alex,"name")
print(ret)
输出:alex
print(getattr(wusir,"name")) #1.(1)反射对象的实例变量
输出:wusir
ret=getattr(wusir,"qqxing") #可以用wusir反射其中的方法
ret() #getattr(wusir,"qqxing") 得到函数地址,函数地址加括号就是调用
输出:qqxing
print(getattr(wusir,"qqxing")()) #1.(2)反射对象的绑定方法
输出:qqxing
666 #print输出qqxing方法的返回值
print(getattr(Person,"Role")) #2.反射类的静态变量
3.引用(1)模块中的任意变量 (2)当前执行的本模块中的内容
(1)
a.py中
class wechat:pass
def sww():
print("爽歪歪")
lst=[1,2,3]
dic={‘k’:‘v’}
we-=wechat()
import a
print(getattr(a,"sww"))#输出方法对应地址
getattr(a,"sww") () 输出:爽歪歪
print(getattr(a,"lst")) #输出[1,2,3]
print((getattr(a,"dic"))#输出{‘k’:‘v’}
print(getattr(a,"we") #输出we地址
(2)
import sys
cat="小a"
dog="小b"
def pig():
print("小 p")
print(getattr(sys.modules['__main__'],'cat'))
getattr(sys.modules['__main__'],'pig')()
输出:小a
小p
反射的另一个函数
hasattr,hasattr和getattr必须配合使用
class A:
self.name=name
self.age=84
def func(self):
print('哇哈哈')
a=A()
print(hasattr(a,"sex")) 输出:False
#hasattr判断某一个对象能不能反射某一个变量
print(hasattr(a,"name"))输出:True
#如果能反射,还要通过callable 判断反射过来的变量的这个值或者内存地址是不是一个可调用或者可执行的,可执行才能加括号,不可执行不能加括号
if hasattr(a,'func')
if callable(getattr(a,"func")):
getattr(a,"func")()