请问这里b.a.x为啥会报错。。?
class A:x = 666
def __get__(self, instance, owner):
print('get~')
def __getattribute__(self, item):
print('getattribute')
class B:
a = A()
a = A()
b = B()
a.x# 通过实例访问属性,都会经过__getattribute__函数。而当该属性不存在时,仍会先访问__getattribute__,但是之后还会接着要访问__getattr__ ,弹出异常。
b.a.x# 每次访问描述符(descriptor)(即定义了__get__的类),都会先经过__get__函数。 class A:
x = 666
def __get__(self, instance, owner):
print('get~')
return self
def __getattribute__(self, item):
print('getattribute a')
return super().__getattribute__(item)
class B:
a = A()
def __getattribute__(self, item):
if item=='a':
print('getattribute b')
return super().__getattribute__(item)
b = B()
print(b.a.x)
'''
getattribute b
get~
getattribute a
666
''' class A:
a = 1
class B:
c = A()
b = B()
print (b.c.a)
我这么写没有报错。。这两个是一回事吧 区别在于
这两个魔法方法被改了
def __get__(self, instance, owner):
print('get~')
def __getattribute__(self, item):
print('getattribute') __get__ 函数你忘了return self kogawananari 发表于 2021-7-20 16:55
__get__ 函数你忘了return self
class A:
x = 666
def __get__(self, instance, owner):
print (self,'self')
print (instance,'instance')
print (owner,'owner')
print('get~')
return self
def __getattribute__(self, item):
print('getattribute')
class B:
a = A()
a = A()
b = B()
#a.x
#print (a,'a')
#print (b,'b')# 通过实例访问属性,都会经过__getattribute__函数。而当该属性不存在时,仍会先访问__getattribute__,但是之后还会接着要访问__getattr__ ,弹出异常。
print (b.a.x ) # 每次访问描述符(descriptor)(即定义了__get__的类),都会先经过__get__函数。
#类方法中定义了__get__就是描述符,从一个类实例访问另一个实例或者它的属性,都会首先触发__get__
我把代码改成这种,结果是:<__main__.A object at 0x000001F6D5753C48> self
<__main__.B object at 0x000001F6D5753D08> instance
<class '__main__.B'> owner
get~
getattribute
None
不知道为啥getattribute被触发了,然后打印了个None?? 杨东明 发表于 2021-7-20 17:07
我把代码改成这种,结果是: self
instance
owner
描述符是这样的 本来就b.a就想让你返回需要的
你要b.a.x只好改成return self 相当于这不是一个描述符了{:10_292:} kogawananari 发表于 2021-7-20 17:15
描述符是这样的 本来就b.a就想让你返回需要的
你要b.a.x只好改成return self 相当于这不是一个描述符 ...
其实优先级只需要区分描述符和非数据描述符与本体的__getattribute__优先级
也就是说你只需要知道 B.__getattribute__和b.描述符谁优先
而不用知道 b.描述符.__getattribute__和b.描述符.__get__谁优先 kogawananari 发表于 2021-7-20 17:17
其实优先级只需要区分描述符和非数据描述符与本体的__getattribute__优先级
也就是说你只需要知道 B._ ...
描述符还分为数据描述符和非数据描述符 优先级也大有区别 kogawananari 发表于 2021-7-20 17:15
描述符是这样的 本来就b.a就想让你返回需要的
你要b.a.x只好改成return self 相当于这不是一个描述符 ...
我码一下我的疑问噢。。1,描述符不是只要一个类里面定义了__get__就是吗?
2.请问这里如何修改b.a.x不会报错,就是如何改正常?
3.还是没懂这个getattribute为何在加了return self会被触发?? 杨东明 发表于 2021-7-20 18:44
我码一下我的疑问噢。。1,描述符不是只要一个类里面定义了__get__就是吗?
2.请问这里如何修改b.a.x不 ...
1. 是的
2. 你的__getattribute__不返回值, 所以print了一个None, 改正常...把get中的语句复制过去, 详见下面的3
3. 任何获取实例属性的行为都会触发__getattribute__, 所以不是return语句触发的, 是b.a.x这句 杨东明 发表于 2021-7-20 18:44
我码一下我的疑问噢。。1,描述符不是只要一个类里面定义了__get__就是吗?
2.请问这里如何修改b.a.x不 ...
你问如何修改b.a.x不会报错
写出__set__方法不久可以修改了吗
数据描述符的意思就是 b.a 等价于 普通对象的b.a.x你对b.a重新赋值 就是修改的b.a.x
kogawananari 发表于 2021-7-20 17:01
请问第五行和第十四行代码print为啥没东西。。?第五行不是返回了一个a吗,十四行是不是返回了a这个实例对象? 学渣李某人 发表于 2021-7-20 21:20
1. 是的
2. 你的__getattribute__不返回值, 所以print了一个None, 改正常...把get中的语句复制过去, 详 ...
如果把ruturn self去掉的话不会触发getattribute,而是报错,AttributeError: 'NoneType' object has no attribute 'x',我想再问问这个报错是哪里报错?这个报错啥意思?是因为在__get__这儿报错就程序就没有往下执行getattrbute了吗? 杨东明 发表于 2021-7-21 15:18
如果把ruturn self去掉的话不会触发getattribute,而是报错,AttributeError: 'NoneType' object has no a ...
b.a.x 相当于访问了两次 __getattribute__
第一次是 b.a,调用了一次,如果没有 return self 就会返回一个 None
后面又要访问 x,如果不返回 self 就是访问 None 的 x 属性,当然会报错 qiuyouzhi 发表于 2021-7-21 16:13
b.a.x 相当于访问了两次 __getattribute__
第一次是 b.a,调用了一次,如果没有 return self 就会返回一 ...
'第一次是 b.a,调用了一次,如果没有 return self 就会返回一个 None',请问这句中的第一次是指A中的__get__吗?第一句话‘b.a.x 相当于访问了两次 __getattribute__’不知道是不是你说错了,是不是说先访问__get__,再访问__getattribute__。。,我这么理解对么:b.a访问__get__,__get__的返回值会传输到__getattribute__中的self参数,所以这里必须return self? qiuyouzhi 发表于 2021-7-21 16:13
b.a.x 相当于访问了两次 __getattribute__
第一次是 b.a,调用了一次,如果没有 return self 就会返回一 ...
class A:
x = 666
def __get__(self, instance, owner):
print('get~')
return self
def __getattribute__(self, item):
print('getattribute a')
return super().__getattribute__(item)
class B:
a = A()
def __getattribute__(self, item):
if item=='a':
print('getattribute b')
return super().__getattribute__(item)
b = B()
print(b.a.x)
'''
getattribute b
get~
getattribute a
666
'''
麻烦再请教一下这个代码为啥return self这一行和B中的return super().__getattribute__(item),print后没打印相应的东西?? 杨东明 发表于 2021-7-21 16:36
'第一次是 b.a,调用了一次,如果没有 return self 就会返回一个 None',请问这句中的第一次是指A中的__ge ...
?
通过实例访问属性,都会经过_getattribute__函数。
关 __get__ 什么事,两次都访问的 _getattribute__
qiuyouzhi 发表于 2021-7-21 17:17
?
关 __get__ 什么事,两次都访问的 _getattribute__
return self是__get__里面的。。 qiuyouzhi 发表于 2021-7-21 17:17
?
关 __get__ 什么事,两次都访问的 _getattribute__
不是访问实例属性才会触发__getattribute__吗?b.a,a不是B的类属性吗?b.a不是访问b的实例属性吗?
页:
[1]