Python 的對象天生擁有一些神奇的方法,它們總被雙下劃線所包圍,它們是面向對象的 Python 的一切。它們是可以給你的類增加魔力的特殊方法,如果你的對象實現(重載)了某一個魔法方法,那麼這個方法就會在特殊的情況下自動被 Python 所調用。
定義實例對象的屬性被訪問時的行為(不管該屬性是否存在,另:通過類名訪問屬性不會調用該方法)
self 表示對象本身,item 是一個字符串,表示屬性名字
默認為 None,返回值會自動返回給觸發它的對象,一般通過return super().getattribute(item) 返回 item 屬性的值。
class MyTest:
def __init__(self, age):
self.age = age
def __getattribute__(self, item):
return super().__getattribute__(item)
sample = MyTest(18)
print(sample.age)
class Tree(object):
def __init__(self, name):
self.name = name
self.cate = "plant"
def __getattribute__(self, obj):
print("哈哈")
return object.__getattribute__(self, obj)
aa = Tree("大樹")
print(aa.name)
執行結果:
哈哈
大樹
為什麼會這個結果呢?
__getattribute__ 是屬性訪問攔截器,就是當這個類的屬性被訪問時,會自動調用類的__getattribute__ 方法。
在上面代碼中,當調用實例對象 aa 的 name 屬性時,不會直接打印,而是把 name 的值作為實參傳進 __getattribute__ 方法中(參數 obj 可任意起名),經過一系列操作後,再把 name 的值返回。Python 中只要定義了繼承 object 的類,就默認存在屬性攔截器,只不過是攔截後沒有進行任何操作,而是直接返回。
可以自己改寫 __getattribute__ 方法來實現相關功能,比如查看權限、打印log日志等。如下代碼:
class Tree(object):
def __init__(self, name):
self.name = name
self.cate = "plant"
def __getattribute__(self, *args, **kwargs):
if args[0] == "name":
print("log 大樹")
return "this is 大樹"
else:
return object.__getattribute__(self, *args, **kwargs)
aa = Tree("大樹")
print(aa.name)
執行結果:
log 大樹
this is 大樹
plant