python中的反射機制,解決模塊動態引入,路由分發

什麼是反射機制

反射是將字符串映射到實例變量或實例方法的一種機制.
常見的應用場景:(1)動態加載模塊(2)web框架的URL路由

學習中的可能遇到了這些需求

(1)你的夥伴封裝好了很多py文件,然後你負責根據不同需求去調用不同模塊。
(2)你寫了一個類,其中封裝了很多方法,這時你需要提供一個統一的入口供其他人調用(類似路由轉發)。
這兩個問題都可以通過反射很好的解決

python中的反射

(1)__import__() 動態加載模塊
(2)hasattr() 判斷實例是否存在字符串對應的屬性
(3)getattr() 獲取字符串對應的屬性
(4)setattr() 將字符串對應的已存在的屬性添加到實例中
(5)delattr() 刪除實例中字符串對應的屬性

解決模塊動態引入問題

def new_method(self):
    print("我是新來的請多關照!")


def main():
    """
    動態導入模塊,並創建類實例執行其中方法
    """
    # 1 動態導入func_001模塊
    func001_module = __import__("src.func_001", fromlist=True)
    print(func001_module)

    # 1.1 判斷是否存在對應類
    if hasattr(func001_module, "Func001"):

        # 2 創建Func001類實例對象
        func001 = getattr(func001_module, "Func001")
        # 2.1 判斷是否存在該方法
        if hasattr(func001, "process"):
            # 2.1.1 獲取process成員方法
            func001_process = getattr(func001, "process")
            # 2.1.2 執行該方法
            func001_process(func001)
        else:
            print("沒有找到對應的方法...")

        # 3 添加像Func001中添加new_method方法
        setattr(func001, "new_method", new_method)
        # 3.1 判斷是否存在該方法
        if hasattr(func001, "new_method"):
            # 3.1.1 獲取new_method成員方法
            func001_new_method = getattr(func001, "new_method")
            # 3.1.2 執行該方法
            func001_new_method(func001)
        else:
            print("沒有成功添加new_method")

        # 4 刪除Func001新增方法
        delattr(func001, "new_method")
        print("是否存在新增方法:", hasattr(func001, "new_method"))
    else:
        print("沒有找到對應的類...")


if __name__ == "__main__":
    main()

路由轉發問題

class User(object):

    def add(self):
        print("新增一名用戶...")

    def delete(self):
        print("刪除一名用戶...")

    def update(self):
        print("更新一名用戶...")

    def select(self):
        print("查詢一名用戶...")

    def before_process(self, method):
        if method == "add":
            self.add()
        elif method == "delete":
            self.delete()
        elif method == "update":
            self.update()
        elif method == "select":
            self.select()
        else:
            print("無效調用")

    def after_process(self, method):
        """
        類似路由轉發
        :param method: str 待調用方法名
        """
        if hasattr(self, method):
            func = getattr(self, method)
            func()
        else:
            print("無效調用")


if __name__ == '__main__':
    user = User()
    # user.before_process(method="add")
    user.after_process(method="delete")

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章