鱼C论坛

 找回密码
 立即注册
查看: 1195|回复: 16

[已解决]求助,为什么一个返回有getattr,另一个没有返回

[复制链接]
发表于 2018-7-19 08:54:29 | 显示全部楼层 |阅读模式
3鱼币
本帖最后由 xue11 于 2018-7-19 08:57 编辑

捕获001.JPG 捕获002.JPG


为什么一个代码打印的是getattribtue 与getattr
而另一张图片代码的返回值是getattribtue
难道是super方法的作用吗?怎么理解?
最佳答案
2018-7-19 08:54:30
xue11 发表于 2018-7-21 17:19
那这句怎么理解呢
return super().__getattribute__(name)
这不是恢复父类的功能吗,这里是找不到父类 ...

super(C,self)  这个应该这么写,  python3可以super()   这个super()就是父类了,  super().__getattribute__(name)就调用了父类的这个方法,不是什么找不到父类的属性的.你要去看看继承这块的东西了,感觉你对这个理解不够.
你在定义的类中部重写了__getattribute__,"."运算就找自己的新定义的__getattribute__,把继承的__getattribute__覆盖了, 说着说着.....你又问回到前面的东西了  再看看我前面给你的回复吧

最佳答案

查看完整内容

super(C,self) 这个应该这么写, python3可以super() 这个super()就是父类了, super().__getattribute__(name)就调用了父类的这个方法,不是什么找不到父类的属性的.你要去看看继承这块的东西了,感觉你对这个理解不够. 你在定义的类中部重写了__getattribute__,"."运算就找自己的新定义的__getattribute__,把继承的__getattribute__覆盖了, 说着说着.....你又问回到前面的东西了 再看看我前面给你的回复吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 08:54:30 | 显示全部楼层    本楼为最佳答案   
xue11 发表于 2018-7-21 17:19
那这句怎么理解呢
return super().__getattribute__(name)
这不是恢复父类的功能吗,这里是找不到父类 ...

super(C,self)  这个应该这么写,  python3可以super()   这个super()就是父类了,  super().__getattribute__(name)就调用了父类的这个方法,不是什么找不到父类的属性的.你要去看看继承这块的东西了,感觉你对这个理解不够.
你在定义的类中部重写了__getattribute__,"."运算就找自己的新定义的__getattribute__,把继承的__getattribute__覆盖了, 说着说着.....你又问回到前面的东西了  再看看我前面给你的回复吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 09:19:27 | 显示全部楼层
本帖最后由 ostrich2016 于 2018-7-19 09:40 编辑

我的理解是这样的。

原理上:调用 __getattribute__() 方法的返回值就是 调用__getattr__() 。

help 是这么写的:

__getattribute__(self, name, /)
        Return getattr(self, name).



第一个,你重写以后就没有调用 __getattr__() 方法。
第二个,你用了 super() 函数来调用了 _getattr__() 方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 19:48:35 | 显示全部楼层
本帖最后由 Python_str 于 2018-7-19 20:14 编辑

是的,就是你调用了  return super().__getattribute__(self, item)   恢复父类(python3默认object) 的功能(因为你重写__getattribute__的时候,把父类的功能覆盖了,python的底层对它封装好一些功能的哦), 因为在在调用对象的方法或属性的时候(也就是".”运算符),都是先调用了魔法方法__getattribute__  当找不到属性的时候才调用_getattr__
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-19 22:45:58 From FishC Mobile | 显示全部楼层
是否可以这样理解?
恢复父类的功能,也即恢复了父类调用__getattribute__(self,name)魔法方法,又因为没有父类对象的属性(这里的t不能作为父类的属性,只能作为对象C的属性),所以才调用__getattr__方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-20 10:05:13 | 显示全部楼层
我也想过来学习一下的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-20 13:23:26 From FishC Mobile | 显示全部楼层
Python_str 发表于 2018-7-19 19:48
是的,就是你调用了  return super().__getattribute__(self, item)   恢复父类(python3默认object) 的功能( ...

是否可以这样理解?
恢复父类的功能,也即恢复了父类调用__getattribute__(self,name)魔法方法,又因为没有父类对象的属性(这里的t不能作为父类的属性,只能作为对象C的属性),所以才调用__getattr__方法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-20 13:24:35 From FishC Mobile | 显示全部楼层
Python_str 发表于 2018-7-19 19:48
是的,就是你调用了  return super().__getattribute__(self, item)   恢复父类(python3默认object) 的功能( ...

如何去判断找不到属性呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-20 13:54:25 | 显示全部楼层
本帖最后由 Python_str 于 2018-7-20 14:26 编辑
xue11 发表于 2018-7-20 13:24
如何去判断找不到属性呢?


__getattribute__来完成的  python底层封装好的功能了   其实自己去写判断实例对象有没有这个属性也很简单
python解释器自动给你传了self(当然这个形参可以是别的,官方推荐使用self)  所以python是知道是谁在调用它  就知道它有没有这个属性了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-20 13:57:56 | 显示全部楼层
本帖最后由 Python_str 于 2018-7-20 14:26 编辑
xue11 发表于 2018-7-20 13:23
是否可以这样理解?
恢复父类的功能,也即恢复了父类调用__getattribute__(self,name)魔法方法,又因为 ...


python解释器自动给你传了self  所以python是知道是谁在调用它    就知道它有没有这个属性了  C是继承了父类的属性 或方法  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 09:14:50 | 显示全部楼层
Python_str 发表于 2018-7-20 13:54
__getattribute__来完成的  python底层封装好的功能了   其实自己去写判断实例对象有没有这个属性也很 ...

>>> class C:
        def __getattribute__(self,name):
                print('getattribute')
                return super().__getattribute__(name)
        def __getattr__(self,name):
                print('getattr')

>>> a = C()
>>> a.t
getattribute
getattr
>>>>>> hasattr(a,'t')
getattribute
getattr
True
#验证属性t 是否为父类object 的属性
>>> hasattr(object,'t')
False

这时t 已经是C 类的属性对吧,是因为重写了getattribute方法对吧,若没有重写则t 并不是C类的属性了,对吧。我在举个例子你看下
>>> class C:
        pass

>>> c = C()
>>> c.t
Traceback (most recent call last):
  File "<pyshell#97>", line 1, in <module>
    c.t
AttributeError: 'C' object has no attribute 't'


也就是确定t 为C 类属性时因为重写了getattribute方法,若没写这个getattribute方法,t 也没有赋值,t并不为属性

是否正确?感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-21 11:23:43 | 显示全部楼层
本帖最后由 Python_str 于 2018-7-21 11:27 编辑

@xue11
>>> class C:
        def __getattribute__(self,name):
                print('getattribute')
                return super().__getattribute__(name)
        def __getattr__(self,name):
                print('getattr')

>>> a = C()
>>> a.t
getattribute
getattr
>>>>>> hasattr(a,'t')
getattribute
getattr
True
#验证属性t 是否为父类object 的属性
>>> hasattr(object,'t')
False

这时t 已经是C 类的属性对吧,是因为重写了getattribute方法对吧,若没有重写则t 并不是C类的属性了,对吧。我在举个例子你看下


这么说是不对的哦

a.t 并不是给C类回或是实例对象a设置属性,就是一个访问或说调用('.'运算),  a.t = 5这是赋值后才算数设置了属性,但只是给实例对象a设置了,只能给自己之用,你在实例化另一个对象是访问不了t的,你可以a.__dir__()查看a的所有属性和方法

hasattr为什么返回时True呢,是因为hasattr通过调用__getattr__根据是否抛出异常来判断属性是否存在的  默认基类里面是没有定义__getattr__这个魔法方法的, 你在C类中定义了,所以是不会有异常抛出的,除非你定义的语句有异常抛出,  而且要是AttributeError这种异常才可以哦   换句话说hasattr是用来处理AttributeError异常的,有异常处理就返回False 没有就返回True

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-21 11:29:11 | 显示全部楼层
xue11 发表于 2018-7-21 09:14
>>> class C:
        def __getattribute__(self,name):
                print('getattribute')

setattr 用着也可以给对象设置设置属性的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 14:48:06 From FishC Mobile | 显示全部楼层
Python_str 发表于 2018-7-21 11:23
@xue11

这么说是不对的哦

>>> class C:
        def __getattribute__(self,name):
                print('getattribute')
                return super().__getattribute__(name)
        def __getattr__(self,name):
                print('getattr')

>>> a = C()
>>> a.t
getattribute
getattr

我好像理解了一些,这是t并不属于a类的属性,t只有赋值了才算作属性。
那a.t是访问,那getattribute魔法方法不是(定义用户访问属性的行为),既然不为属性,何来访问调用这个getattribute方法?(原谅这么问,实在不理解)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-21 15:12:51 | 显示全部楼层
本帖最后由 Python_str 于 2018-7-21 15:22 编辑
xue11 发表于 2018-7-21 14:48
>>> class C:
        def __getattribute__(self,name):
                print('getattribute')


哈哈  那是"."运算 的时候, 解释器会自动__getattribute__

而a.t = value 的时候 就调用这个魔法方法的哦 __setattr__ 不会调用__getattribute__的哦


我好像理解了一些,这是t并不属于a类的属性,t只有赋值了才算作属性
a是一个C类的实例对象 不是a类 这种说法不对哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 17:18:38 From FishC Mobile | 显示全部楼层
那这句怎么理解呢
return super().__getattribute__(name)
这不是恢复父类的功能吗,这里是找不到父类的属性吗,我记得找不到属性调用getattr方法的,找不到这个属性指的是什么属性,如何断定能否找到呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 17:19:19 From FishC Mobile | 显示全部楼层
Python_str 发表于 2018-7-21 15:12
哈哈  那是"."运算 的时候, 解释器会自动__getattribute__

而a.t = value 的时候 就调用这个魔法方 ...

那这句怎么理解呢
return super().__getattribute__(name)
这不是恢复父类的功能吗,这里是找不到父类的属性吗,我记得找不到属性调用getattr方法的,找不到这个属性指的是什么属性,如何断定能否找到呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 23:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表