Python的__getattribute__ vs __getattr__的妙用
這里的屬性即包括屬性變量,也包括屬性方法。即類的變量和方法。
當(dāng)訪問某個實(shí)例屬性時(shí), getattribute會被無條件調(diào)用,如未實(shí)現(xiàn)自己的getattr方法,會拋出AttributeError提示找不到這個屬性,如果自定義了自己getattr方法的話,方法會在這種找不到屬性的情況下被調(diào)用,比如上面的例子中的情況。
所以在找不到屬性的情況下通過實(shí)現(xiàn)自定義的getattr方法來實(shí)現(xiàn)一些功能是一個不錯的方式,因?yàn)樗粫駁etattribute方法每次都會調(diào)用可能會影響一些正常情況下的屬性訪問
使用這幾個方法可以實(shí)現(xiàn)攔截器啥、動態(tài)代理、統(tǒng)一log等功能。
舉例:
1、使用__getattribute__實(shí)現(xiàn)統(tǒng)一的打印日志功能。使用__getattribute__方法攔截了屬性和方法的訪問。__getattribute__只有在新式類中才能使用。
# -*- coding: utf-8 -*- class Fjs(object):def __init__(self, name):self.name = namedef hello(self):print "said by : ", self.namedef __getattribute__(self, item):print "訪問了特性:" + itemreturn object.__getattribute__(self, item)fjs = Fjs("fjs") print fjs.name fjs.hello()輸出:
訪問了特性:name fjs 訪問了特性:hello said by : 訪問了特性:name fjs2、這里通過__getattr__方法,將所有的特性的訪問都路由給了內(nèi)部的fjs對象
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # -*- coding: utf-8 -*- class Fjs(object):def __init__(self, name):self.name = namedef hello(self):print "said by : ", self.namedef fjs(self, name):if name == self.name:print "yes"else:print "no"class Wrap_Fjs(object):def __init__(self, fjs):self._fjs = fjsdef __getattr__(self, item):if item == "hello":print "調(diào)用hello方法了"elif item == "fjs":print "調(diào)用fjs方法了"return getattr(self._fjs, item)fjs = Wrap_Fjs(Fjs("fjs")) fjs.hello() fjs.fjs("fjs")輸出:
調(diào)用hello方法了 said by : fjs 調(diào)用fjs方法了 yes3、使用類的繼承實(shí)現(xiàn)。則不會路由,子類直接繼承了父類的屬性和方法
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # -*- coding: utf-8 -*- class Fjs(object):def __init__(self, name):self.name = namedef hello(self):print "said by : ", self.namedef fjs(self, name):if name == self.name:print "yes"else:print "no"class Wrap_Fjs(Fjs):def __init__(self, fjs):self._fjs = fjsdef __getattr__(self, item):if item == "hello":print "調(diào)用hello方法了"elif item == "fjs":print "調(diào)用fjs方法了"return getattr(self._fjs, item)fjs = Wrap_Fjs(Fjs("fjs")) fjs.hello() fjs.fjs("fjs")輸出:
said by : fjs yes4、猜一下結(jié)果,理解其妙用
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' # 例子在原來的基礎(chǔ)上簡化了一下,排除依賴和干擾,詳細(xì)參見原項(xiàng)目 class UrlGenerator(object):def __init__(self, root_url):self.url = root_urldef __getattr__(self, item):if item == 'get' or item == 'post':print self.urlreturn UrlGenerator('{}/{}'.format(self.url, item))url_gen = UrlGenerator('http://xxxx') url_gen.users.show.get5、通過轉(zhuǎn)換,可以像訪問屬性一樣訪問dict中的鍵值對
class ObjectDict(dict):def __init__(self, *args, **kwargs):super(ObjectDict, self).__init__(*args, **kwargs)def __getattr__(self, name):value = self[name]if isinstance(value, dict):value = ObjectDict(value)return valueif __name__ == '__main__':od = ObjectDict(asf={'a': 1}, d=True)print od.asf, od.asf.a # {'a': 1} 1print od.d # True總結(jié)
以上是生活随笔為你收集整理的Python的__getattribute__ vs __getattr__的妙用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中取整数的几种方法
- 下一篇: python常用8大算法