时间:2020.12.09
环境:Python3
目的:反射常用的方法使用
说明:
作者:Zhong QQ交流群:121160124 欢迎加入!
需求
需要执行或调用对象或函数中的某个方法或变量,但不确定此方法或变量是否存在!例如如下的示例代码:
class Animal():
def __init__(self, name, weight):
self.name = name
self.weight = weight
def info(self):
print(self.name)
print(self.weight)
# 实例化一个对象
rabbit = Animal("兔子", 5)
"""
hasattr
使用hasattr方法查看对象中是否有某个方法或变量
"""
# 查看rabbit对象中是否有name属性(方法或变量)
print(hasattr(rabbit, "name")) # True
# 查看rabbit对象中是否有info属性(方法或变量)
print(hasattr(rabbit, "info")) # True
# 查看rabbit对象中是否有behavior属性(方法或变量)
print(hasattr(rabbit, "behavior")) # False
"""
getattr
使用getattr方法获取对象中的方法内存地址或变量
"""
# 获取rabbit对象中name属性(方法或变量)
print(getattr(rabbit, "name")) # name为变量 输出变量值:兔子
# 获取rabbit对象中info属性(方法或变量)
print(getattr(rabbit, "info")) # info为方法 输出方法描述:<bound method Animal.info of <__main__.Animal object at 0x00000242938A8EB0>>
# 获取rabbit对象中behavior属性(方法或变量)
# print(getattr(rabbit, "behavior")) # 没有behavior属性 输出属性错误提示:AttributeError: 'Animal' object has no attribute 'behavior'
# 获取rabbit对象中behavior属性(方法或变量)
print(getattr(rabbit, "behavior", "没有此属性")) # 没有behavior属性 输出自定义提示信息:没有此属性
"""
setattr(不常用)
使用setattr为对象添加变量或方法
"""
"""
delattr(不常用)
删除对象中的变量(不能删除对象中的方法)
"""
使用场景
策略管理API,根据前端用户传入的参数action动态调用相应的方法返回结果。如果使用if else等语句判断参数逐个匹配,不但要写很多代码,而且维护也繁琐,此时可以使用python反射借助getattr()方法实现。
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from casbin_middleware.middleware import enforcer
from rbac.models import CasbinRule
class PolicyManagement(APIView):
def __init__(self):
super().__init__()
self.e = enforcer
self.action = ""
def get(self, request):
try:
username = request.user.username
args = request.query_params
self.action = func_name = request.query_params.get("action")
func = getattr(self, func_name, self.func_not_found)
res_data = func(args)
res_data = {
"username": username,
"data": res_data
}
return Response(data=res_data, status=status.HTTP_200_OK)
except Exception as e:
return Response(data=e, status=status.HTTP_400_BAD_REQUEST)
# get方法中调用 如果没有对应的方法则调用此方法
def func_not_found(self, *args, **kwargs): # just in case we dont have the function
print("没有此方法 " + self.action)
return "参数error!没有此方法 %s" % self.action
# 获取当前策略中显示的主题列表
def GetAllSubjects(self, args, **kwargs):
res_data = self.e.get_all_subjects()
return res_data
# 获取当前命名策略中显示的主题列表
def GetAllNamedSubjects(self, args, **kwargs):
res_data = self.e.get_all_named_subjects(ptype=args['ptype'])
return res_data
# 获取当前策略中显示的对象列表
def GetAllObjects(self, args, **kwargs):
res_data = self.e.get_all_objects()
return res_data
# 获取当前命名策略中显示的对象列表
def GetAllNamedObjects(self, args, **kwargs):
res_data = self.e.get_all_named_objects(ptype=args['ptype'])
return res_data
# 获取当前策略中显示的操作列表
def GetAllActions(self, args, **kwargs):
res_data = self.e.get_all_actions()
return res_data
# 获取当前命名策略中显示的操作列表
def GetAllNamedActions(self, args, **kwargs):
res_data = self.e.get_all_named_actions(ptype=args['ptype'])
return res_data
# 获取当前策略中显示的角色列表
def GetAllRoles(self, args, **kwargs):
res_data = self.e.get_all_roles()
return res_data
# 获取当前命名策略中显示的角色列表
def GetAllNamedRoles(self, args, **kwargs):
res_data = self.e.get_all_named_roles(ptype=args['ptype'])
return res_data
# 获取策略中的所有授权规则
def GetPolicy(self, args, **kwargs):
# res_data = self.e.get_policy()
objects_all = CasbinRule.objects.all().values("id", "ptype", "casbinrulemap__name")
for obj in objects_all:
print(obj)
res_data = {}
return res_data
# 获取策略中的所有授权规则,可以指定字段筛选器
def GetFilteredPolicy(self, args, **kwargs):
res_data = self.e.get_filtered_policy(int(args['field_index']), args['name'])
return res_data
关注微信公众号