Python 如何使用函数/方法名实现函数/方法调用
本篇文章主要介绍:如何将通过方法名/函数名(str 类型),实现对该函数/方法的调用。以下将从:场景、实现、方法原理三个方面进行说明。另外,方法和函数大致上是相同的,只是函数是一段代码,通过名字来进行调用,方法也是一段代码,也通过名字来进行调用,但它跟一个对象相关联
1. 场景与实现
1.1 方法场景
在一些代码编写场景中,我们可能会遇到这样:
class SendMessage():
...
_hanler_map_items = [
dict(type_name="修改密码", type_value=1, handler="_modify_password_handler"),
dict(type_name="重置密码", type_value=2, handler="_reset_password_handler")
]
def send(self, type_value: int) -> None:
pass
def _modify_password_handler(self, *args, **kwargs) -> None:
pass
def _reset_password_handler(self, *args, **kwargs) -> None:
pass
我定义了一个类 SendMessage
,这个类中,我定义了统一的调用界面 send
,在类属性中,我定义了_hanler_map_items
这样一个映射列表,这个列表的目的就是根据不同的 type_value
映射到对应的 handler
handler
的 value
是不可以直接选择方法(self._modify_password_handler),因为代码执行时,一行一行加载,此时方法没有加载,就会报错,因此,写上方法名,但是方法名是字符串,不可以直接调用
1.2 方法场景实现
1.2.1 通过 methodcaller() 实现
from operator import methodcaller
handler_name = "_modify_password_handler"
handler_func = methodcaller(handler_name, *args, **kwargs)
handler_func(self)
1.2.2 通过 getattr() 实现
handler_name = "_modify_password_handler"
handler_func = getattr(self, handler_name)
handler_func(self, *args, **kwargs)
1.3 函数场景
函数场景类似,
function_names = ["foo", "bar"]
def foo():
print("foo")
def bar():
print("bar")
for function in function_names:
function()
1.4 函数场景实现
1.4.1 通过 eval() 实现
for function_name in function_names:
function = eval(function_name)
function()
# foo
# bar
1.4.2 通过 locals() 和 globals()
for function_name in function_names:
function = locals()[function_name]
function()
# foo
# bar
for function_name in function_names:
function = globals()[function_name]
function()
# foo
# bar
2. 实现原理
2.1 methodcaller() 实现原理
methodcaller 函数的定义可以理解为:
def methodcaller(function_name, *args, **kwargs):
def caller(obj):
return getattr(obj, function_name)(*args, **kwargs)
return caller
可以看到这是一个闭包,返回的是一个可以调用的函数对象函数,并且可以传递参数给最终要调用的方法
2.2 getattr() 介绍
- 作用:函数用于返回一个对象属性值
- 语法:getattr(object, name[, default])
- 参数:
- object:对象
- name:字符串,对象属性
- default: 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError
2.3 globals() 介绍
- 作用:函数会以字典类型返回当前位置的全部全局变量
- 语法:globals()
2.4 locals() 介绍
- 作用:函数会以字典类型返回当前位置的全部局部变量
- 语法:locals()
2.5 eval() 介绍
- 作用:函数用来执行一个字符串表达式,并返回表达式的值
- 语法:eval(expression[, globals[, locals]])
- 参数:
- expression :表达式
- globals:变量作用域,全局命名空间,如果被提供,则必须是一个字典对象
- locals:变量作用域,局部命名空间,如果被提供,可以是任何映射对象