2022年1月3日 星期一

Python:反射、getattr、 __getattr__

反射 (reflection) 指的是在程式執行時操作(存取、修改、刪除)其本身狀態的能力。在 Python 之中是用字串搭配以下函數達成此目標:

  • hasattr
  • getattr
  • setattr
  • delattr
以下為一個例子:
module_str = input("module: ")
func_str = input("func: ")
m = __import__("lib." + module_str)

if hasattr(m, func_str):
    target_func = getattr(m, func_str)
    target_func()

用這種方法就能在執行時直接將輸入的字串與函數連結在一起,另外在實作時也能避免許多的 if-else 程式碼。

__getattr__ 與 __getattribute__ 的差別

在呼叫一個 instance 的 components 時,會先呼叫其中定義(或繼承的)__getattribute__ 函數,而若是不存在的話才會呼叫 __getattr__ 函數。以下為一個例子:

class A(object):
    num = 123
    def __init__(self, name):
        self.name = name

    def __getattribute__(self, name):
        print("Calling __getattribute__")
        return object.__getattribute__(self, name)

    def __getattr__(self, name):
        print("Calling __getattr__")
        return None

a = A("John")
print(a.name)
# Calling __getattribute__
# John
print(a.num)
# Calling __getattribute__
# 123
print(a.xyz)
# Calling __getattribute__
# Calling __getattr__
# None

沒有留言:

張貼留言