鱼C论坛

 找回密码
 立即注册
查看: 985|回复: 9

[已解决]求助getattr 魔法方法的用法

[复制链接]
发表于 2018-7-19 10:43:19 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 xue11 于 2018-7-19 10:44 编辑

代码1
>>> class Demo:
        def __getattr__(self,name):
                return "属性不存在"

       
>>> demo = Demo()
>>> demo.x
'属性不存在'


代码2:
>>> class Demo:
        def __getattr__(self,name):
                return "属性不存在"
        def __getattribute__(self,name):
                print(100)

               
>>> demo = Demo()
>>> demo.x
100

问题1:代码1好理解,当属性不存在时,会调用getattr方法,会有个返回值
而代码2 用demo.x 去访问,调用getattribute方法可以理解,而此时不也是属性x 不存在吗?,为什么不调用getattr魔法方法啊?同样都是访问属性啊
最佳答案
2018-7-19 10:43:20
xue11 发表于 2018-7-21 14:57
---- 这个属性是子类的不过是调用父类的方法去处理。
  1. >>> c= C()
  2. >>> c.x
  3. Traceback (most recent call last):
  4.   File "<pyshell#39>", line 1, in <module>
  5.     c.x
  6. AttributeError: 'C' object has no attribute 'x'
  7. >>> hasattr(c, 'x')
  8. False
  9. >>> c.x = 3
  10. >>> hasattr(c, 'x')
  11. True
复制代码

x是c的属性,但getattribute和getattr你都没有自己编写,都是继承父类的方法。

最佳答案

查看完整内容

x是c的属性,但getattribute和getattr你都没有自己编写,都是继承父类的方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 10:43:20 | 显示全部楼层    本楼为最佳答案   
xue11 发表于 2018-7-21 14:57
---- 这个属性是子类的不过是调用父类的方法去处理。
  1. >>> c= C()
  2. >>> c.x
  3. Traceback (most recent call last):
  4.   File "<pyshell#39>", line 1, in <module>
  5.     c.x
  6. AttributeError: 'C' object has no attribute 'x'
  7. >>> hasattr(c, 'x')
  8. False
  9. >>> c.x = 3
  10. >>> hasattr(c, 'x')
  11. True
复制代码

x是c的属性,但getattribute和getattr你都没有自己编写,都是继承父类的方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 10:54:48 | 显示全部楼层
return 只是返回那个字符串,用print打印出来就欧克了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 10:58:39 | 显示全部楼层
当同时定义 __getattribute__ 和 __getattr__ 时,__getattr__ 方法不会再被调用,除非显示调用 __getattr__ 方法或引发 AttributeError 异常
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-19 11:10:23 | 显示全部楼层
缺省的__getattribute__会自动调用__getattr__,你自己重新定义后,就没有这个操作了,加上super即可
  1. class Demo:
  2.         def __getattr__(self,name):
  3.                 return "属性不存在"
  4.         def __getattribute__(self, name):
  5.                 print(100)
  6.                 return super().__getattribute__(name)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 09:31:55 | 显示全部楼层
冬雪雪冬 发表于 2018-7-19 11:10
缺省的__getattribute__会自动调用__getattr__,你自己重新定义后,就没有这个操作了,加上super即可

>>> class Demo:
        def __getattr__(self,name):
                return "属性不存在"
        def __getattribute__(self, name):
                print(100)
                return super().__getattribute__(name)

        
>>> d = Demo()
>>> d.x
100
'属性不存在'

若加上super之后,可以正常调用__getattr__方法了。还有两个问题在请教下
(1)这时x为Demo 类的属性吗?是因为重写了__getattribute__方法吗,对吧,例如:
>>> hasattr(d,'x')
100
True
又例如:
>>> class C:
        pass

>>> c = C()
>>> c.x
Traceback (most recent call last):
  File "<pyshell#96>", line 1, in <module>
    c.x
AttributeError: 'C' object has no attribute 'x'
这时 x 不为C 类的属性,是因为未重写getattribute魔法方法对吧?也就是说getattribute 魔法方法可以定义属性对吗?
(2)加上super,也即恢复了父类的功能,而所有的类默认继承object 类,所以这时x 并不为父类的属性,所以会调用getattr 魔法方法。例如
>>> hasattr(object,'x')
False
#可以证明x 并不为父类的属性

这样理解是否正确?

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

使用道具 举报

发表于 2018-7-21 11:28:49 | 显示全部楼层
getattribute 魔法方法可以定义属性对吗?
---- 不是,没有编写此方法,得到AttributeError: 'C' object has no attribute 'x',编写了得到'属性不存在',都是一样的,python的变量不需要先定义再赋值,使用d.x在没有赋值前都是不存在的。

#可以证明x 并不为父类的属性
---- 这个属性是子类的不过是调用父类的方法去处理。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 14:56:18 From FishC Mobile | 显示全部楼层
冬雪雪冬 发表于 2018-7-21 11:28
getattribute 魔法方法可以定义属性对吗?
---- 不是,没有编写此方法,得到AttributeError: 'C' object h ...

>>> class Demo:
        def __getattr__(self,name):
                return "属性不存在"
        def __getattribute__(self, name):
                print(100)
                return super().__getattribute__(name)

        
>>> d = Demo()
>>> d.x
100
'属性不存在'

既然d没有属性x,为什么还调用getattribute魔法方法,这个魔法方法的意思不就是(定义用户访问属性的行为),既然无属性,为什么还访问?
那这时t算作什么,算作不存在的属性吗,那不是就应该调用getattr魔法方法吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-21 14:57:15 From FishC Mobile | 显示全部楼层
冬雪雪冬 发表于 2018-7-21 11:28
getattribute 魔法方法可以定义属性对吗?
---- 不是,没有编写此方法,得到AttributeError: 'C' object h ...

---- 这个属性是子类的不过是调用父类的方法去处理。


这句话是什么意思啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-21 15:00:44 | 显示全部楼层
xue11 发表于 2018-7-21 14:56
>>> class Demo:
        def __getattr__(self,name):
                return "属性不存在"

当调用一个属性时就是调用getattribute魔法方法,如果有此属性,则用getattribute给出值,如果没有再继续调用getattr返回错误信息。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-28 21:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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