第六章 反射
1 什么是反射
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。
反射的概念是由Smith在1982年首次提出的,这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp
和面向对象方面取得了成绩。
python面向对象中的反射:通过字符串的形式操作对象相关的属性
python中的一切事物都是对象,都可以使用反射
在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射
2 用作反射的四个喊
hasattr(object, 'attrName') #判断一个对象中是否存在某个属性
setattr(object, 'attrName', value) # 给对象设置一个属性
getattr(object, 'attrName' [,defaultValue=None]) # 获取某个属性的值,可以指定默认值
delattr(object, 'attrName') # 删除对象中指定的属性
# 四个方法 使用演示
class Teach:
feature='Ugly'
def __init__(self,name,age):
self.name=name
self.age=age
def eat():
print('老子爱吃')
def drink():
print('老子爱睡')
b1=Teach('丹丹', 18)
#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))
#获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'drink')
func()
# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))
#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))
#删除属性
delattr(b1,'age')
delattr(b1,'eat')
delattr(b1,'show_name111')#不存在,则报错
print(b1.__dict__)
# 模块导入之后,被作为一个对象,模块内的全局变量成为模块对象的属性
import sys
print(hasattr(sys, 'path'))
print(hasattr(sys, 'argv'))
setattr(sys, 'path', '哈哈,被我改了')
print(sys.path)
delattr(sys, 'path')
# print(sys.path) # 报错
3 反射实现模块动态导入
# 两种方式
# 第一种,内置函数
变量名 = __import__('模块名', globals=None, locals=None, fromlist=(), level=0)
# 第二种 importlib模块
import importlib
变量名 = importlib.import_module('模块名', package=None)
import importlib
modName=input("请输入模块名:")
#__import__:根据字符串输入的模块名导入相对应得模块
name= importlib.import_module(modName)
print(modName)
funcName=input("请输入fan方法(函数)名:")
#检查模块中是否相对应得函数
exis=hasattr(name,funcName)
if exis:
#获得函数
fun=getattr(name,funcName)
#执行函数
fun()
else:
print("模块中没有这个方法")
4 反射WEB开发动态处理URL
# 动态导入模块,并执行其中函数
url = input("url: ")
target_module, target_func = url.split('/')
m = __import__('lib.'+target_module, fromlist=True)
inp = url.split("/")[-1] # 分割url,并取出url最后一个字符串
if hasattr(m,target_func): # 判断在commons模块中是否存在inp这个字符串
target_func = getattr(m,target_func) # 获取inp的引用
target_func() # 执行
else:
print("404")