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:變量作用域,局部命名空間,如果被提供,可以是任何映射對象