假如现在一个场景,需要根据用户输入的url,调用不同的函数,实现不同的操作,也就是一个url路由器的功能,这在web框架里是核心部件之一。下面是小A的实现方法:
# author:别动我名字
# contact:
# datetime:2019/4/10 22:36
# software: PyCharm Community Edition
"""
文件说明: 反射
"""
class MyClass():
"""
MyClass用于实现不同方法的调用
"""
def login(self):
print("这是一个登陆页面!")
def logout(self):
print("这是一个退出页面!")
def home(self):
print("这是网站主页面!")
# 这里可以接收用户输入的内容
inp = input("请输入您想访问页面的url: ").strip() # 这里可以输入login
# 有人可能想到,直接在对象后面拼接用户输入的变量。但是在调用MyClass的时候它并不会认为你是个变量
# MyClass().inp()
# 报错 AttributeError: 'MyClass' object has no attribute 'inp'
# 正确实现方式
my=MyClass()
if inp == "login":
my.login()
elif inp == "logout":
my.logout()
elif inp == "home":
my.home()
else:
print("404")
以上部分小a就实现了根据用户输入的不同url执行不同函数,但是如果模块有很多函数,全部都要if elif来实现吗?这时候就需要用到反射了
class MyClass():
"""
MyClass用于实现不同方法的调用
"""
def login(self):
print("这是一个登陆页面!")
def logout(self):
print("这是一个退出页面!")
def home(self):
print("这是网站主页面!")
my=MyClass()
inp = input("请输入您想访问页面的url: ").strip()
if hasattr(my, inp): # 用于判断my对象中是否具有inp成员,是则返回True,没有则返回False
func=getattr(my, inp) # 它接收2个参数,前面的是一个对象或者模块,后面的是一个字符串,注意了!是个字符串!返回内存地址
print(func)# <bound method MyClass.login of <__main__.MyClass object at 0x00000150A67F6668>>
func()
else:
print("404")
总结:
hasattr(obj,name_str)判断对象obj中是否包含name_str字符串的方法
getattr(obj,name_str)根据字符串name_str获取对象obj对象中的内存地址