htyj0 发表于 2021-3-22 17:48:41

代码求解释

下面是一段描述符类的代码
class MyDescrpr:                        #定义一个描述符类
    def __init__(self, value = 'X-man!'):      
      self.value = value
   
    def __get__(self, instance, owner):
      print('getting... ', self, instance, owner)
      return self.value

    def __set__(self, instance, value):
      print('setting... ', self, instance, value)
      self.value = value

class Test:
    d = MyDescrpr()

t = Test()               
print(t.d)               
t.d = 5
print(t.d)

以下是输出结果:
==================== RESTART: F:/python/desper.py ===================
getting...<__main__.MyDescrpr object at 0x0000000002D30520> <__main__.Test object at 0x0000000002F99FA0> <class '__main__.Test'>
X-man!
setting...<__main__.MyDescrpr object at 0x0000000002D30520> <__main__.Test object at 0x0000000002F99FA0> 5
getting...<__main__.MyDescrpr object at 0x0000000002D30520> <__main__.Test object at 0x0000000002F99FA0> <class '__main__.Test'>
5

有一点还是不太理解,在Test类中,d是一个描述符类的对象,为什么能对一个对象进行直接赋值呢,为什么不能像其他普通的类一个,直接为其新建一个属性并赋值,比如:
>>> t.d.y = 3
这里会报错:
getting...<__main__.MyDescrpr object at 0x0000000002D30520> <__main__.Test object at 0x0000000002F99FA0> <class '__main__.Test'>
Traceback (most recent call last):
File "<pyshell#96>", line 1, in <module>
    t.d.y = 3
AttributeError: 'int' object has no attribute 'y'

而在普通的类中:
class A:
    pass

class B:
    a = A()

b = B()
b.a.x = 1                        # 这样赋值是允许的
print(b.a.x)

输出结果:1

Cool_Breeze 发表于 2021-3-22 18:03:16

t.d = 5; d是int类型, int类型没有属性y
t.d = Test() ;
t.d.y = 3;这样就行啦。 d的类型为 Test的实例

MachineGirl 发表于 2021-3-22 18:48:54

我只知道是因为,你重写了MyDescrpr里边的get方法
时间有点久了,忘了__get__()原本是怎么运作的了

htyj0 发表于 2021-3-22 22:00:40

MachineGirl 发表于 2021-3-22 18:48
我只知道是因为,你重写了MyDescrpr里边的get方法
时间有点久了,忘了__get__()原本是怎么运作的了

嗯,也许这就是描述符类的特别之处吧。

查了一点资料,对这个问题有一点粗浅的认识,也加深对“python万物皆对象”的理解。

>>> a = 2
>>> type(a)
<class 'int'>   #可见整形也是一个类,给一个变量赋整数值,相当于实例化int类的一个对象

描述符类定义了__get__()方法,调取该类的对象时会python会自动该重写后的方法,并将对象类型确定为该方法的返回值类型。

从这个意义上讲,这里的t.d = 5和没有定义任何符类时没有什么区别。

一旦被赋值,类型自然就确定了,整型当然是没有y属性的,所以才会报错 'int' object has no attribute 'y'。

而在下面的那个例子中,b.a返回的是一个普通的类的对象,当然可以为它赋任何类型的值。

不知道说的对不对。

htyj0 发表于 2021-3-22 22:02:47

Cool_Breeze 发表于 2021-3-22 18:03
t.d = 5; d是int类型, int类型没有属性y
t.d = Test() ;
t.d.y = 3;这样就行啦。 d的类型为 Test的实例

是这样的。只是里面用到的描述符类运行的内部机制还不是理得太明白,所以有点困惑。谢谢了。

Stubborn 发表于 2021-3-22 23:04:01

需要实现对应的魔法方法,我没记错的应该是settar好像是这个,实现之后就可以设置

htyj0 发表于 2021-3-24 08:22:06

谢谢。
页: [1]
查看完整版本: 代码求解释