韩漫免费漫画在线观看方法,《好好疼爱里面》免费看,年轻漂亮的女士护士内衣,妈妈醉酒后把我当爸爸电视剧

文章 > Python基础教程 > Python魔法方法之__getattr__和getattribute

Python魔法方法之__getattr__和getattribute

头像

爱喝马黛茶的安东尼

2019-07-03 13:16:326234浏览 · 0收藏 · 0评论

在Python中有这两个魔法方法容易让人混淆:__getattr__和getattribute。通常我们会定义__getattr__而从来不会定义getattribute,下面我们来看看这两个的区别。

__getattr__魔法方法

class MyClass:
    def __init__(self, x):
        self.x = x
    def __getattr__(self, item):
        print('{}属性为找到!'.format(item))
        return None
>>> obj = MyClass(1)
>>> obj.x
1
>>> obj.y
y属性为找到!
None

我们定义一个MyClass类,设置一个实例属性为x,值为1。obj为这个类的实例,获取obj.x返回1,而获取obj.y发现属性找不到,原因是obj的实例变量中不包含y,找不到某属性时会调用__getattr__方法。

**调用__getattr__详细过程如下:**

obj.attr

1.首先会在对象的实例属性中寻找,找不到执行第二步

2.来到对象所在的类中查找类属性,如果还找不到执行第三步

3.来到对象的继承链上寻找,如果还找不到执行第四步

4.调用obj.__getattr__方法,如果用户没有定义或者还是找不到,抛出AttributeError异常,属性查找失败!

class MyClass:
    def __init__(self, x):
        self.x = x
>>> obj = MyClass(1)
>>> obj.y
AttributeError: 'MyClass' object has no attribute 'a'

如上代码,没有定义__getattr__魔法方法,又找不到属性,就会抛出异常。

相关推荐:《Python视频教程

__getattribute__魔法方法

当我们调用对象的属性时,首先会调用__getattribute__魔法方法。

obj.x
obj.__getattribute__(x)

如上代码,这两个代码其实是等价的。当__getattribute__查找失败,就会去调用__getattr__方法。

代码演示

class MyClass:
    def __init__(self, x):
        self.x = x
    def __getattribute__(self, item):
        print('正在获取属性{}'.format(item))
        return super(MyClass, self).__getattribute__(item)
>>> obj = MyClass(2)
>>> obj.x
正在获取属性x
2

我们使用__getattribute__魔法方法时,要返回父类的方法,不然很难写对,下面代码是一个陷阱,会产生递归。

class MyClass:
    def __init__(self, x):
        self.x = x
    def __getattribute__(self, item):
        print('正在获取属性{}'.format(item))
        return self.item
        
>>> obj = MyClass(2)
>>> obj.x
  File "xxx", line 11, in __getattribute__
    print('正在获取属性{}'.format(item))
RecursionError: maximum recursion depth exceeded while calling a Python object

上面的代码看起来似乎是对的,但却调入了递归的陷阱,相当于

def __getattribute__(self, item):
    print('正在获取属性{}'.format(item))
    return self.__getattribute__(item)

要十分警惕。

另外,内置的getattr和hasattr也会触发这个魔法方法。

>>> getattr(obj, 'x', None)
正在获取属性x
2
>>> hasattr(obj, 'x', None)
正在获取属性x
True

其他细节需要注意

class MyClass:
    x = 999
    
    def __init__(self, x):
        self.x = x
    def __getattribute__(self, item):
        print('正在获取属性{}'.format(item))
        return super(MyClass, self).__getattribute__(item)

上面代码中,定义了一个类属性x和一个实例属性x,这两个属性同名,根据Python语法规则,当对象获取属性x的时候,首先会在实例属性中寻找,如果找不到才回去类属性中查找。

>>> obj = MyClass(2)
>>> print(obj.x)
正在获取属性x
2
>>> del obj.x  #删除了实例属性x
>>> print(obj.x)  #此时访问的是类属性
正在获取属性
999

这样就能印证了上面所说__getattribute__的查找顺序。通常该方法在框架中可能会用到,一般情况下无需使用。

关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

刀郎个人简历| 黑料门-今日黑料-每日大赛| 闺蜜老公把我压在怀里| YY影院免费观看电视剧网站| 调教男爵夫人| 日产MV和欧美MV的外观对比| 丈夫不在家儿媳想老公的背景故事| 美国巜性来潮喷1| 姐姐片多多免费高清电视剧| BOBO浏览器| 免费观看已满十八岁电视剧日剧 | 真爱禁区电视剧免费观看全集| 《完美邻居2》电影在线观看| 巨乳童颜| 女子监狱理伦A片| 两个男人睡一个女人什么心理呢 | 40岁女人如饥似渴最佳解决方法| 公交车舒婷的奶头被农民工吸了| 妈妈和女婿免费播放电视剧| 90多岁老太太阴部下坠怎么办| 蜜桃成熟时33D 在线观看| 人野兽马狗猪大全| 乡村玉米地周婶的小说叫什么名字 | 女人大阴唇夹缝是阴虚还是阳虚| 第一次性接触!| 李丽珍| 苏畅| 器材室轮-J-(1):蒙着眼在...| 《性爽2》电影| 水手服| 亚洲| 暴躁老阿姨CSGO最强武器搭配| 借种之灭门惨案2国语版电影| 少女たちよ观看免费高清电视剧| 粗大的蘑菇头刮得又红又肿怎么办| 他的巨物撑开她的花缝的导演是谁| 日本儿子娶母亲的电视剧| 《玉浦困之初入桃花之风雨山应》…| 伦理《少妇的滋味》完整版| 《工地夫妻》原声版| 伦理《禁忌6》