鬼少 发表于 2024-10-23 21:43:04

关于property应用问题

现有如下一段代码:
class Myproperty:
    def __init__(self,fget = None,fset = None,fdel = None):
      self.fget = fget
      self.fset = fset
      self.fdel = fdel

    def __get__(self,instance,owner):
      return self.fget(instance)
   
    def __set__(self,instance,value):
      self.fset(instance,value)
      
    def __delete__(self,instance):
      self.fdel(instance)


class C:
    def __init__(self):
      self._x = None

    def getX(self):
      print('getX')
      return self._x
   
    def setX(self,value):
      print('setX')
      self._x = value

    def delX(self):
      print('delX')
      del self._x

    x = Myproperty(getX,setX,delX)

当运行如下代码时:
>>>c1 = C()
>>>c1.x = 'blue'
>>>setX
>>>c1.x
>>>
getX
'blue'
>>>c1._x
>>>'blue'

疑问: 当执行c1._x时, 为何其值也变为'blue', 而且不在打印'getX', 这是为什么呢?

FishC 发表于 2024-10-23 21:44:12

在您的代码中,`c1.x` 的访问和修改是通过 `Myproperty` 类的描述符方法来处理的。具体来说:

1. 当执行 `c1.x = 'blue'` 时,调用的是 `__set__` 方法,这会触发 `setX` 方法,将 `'blue'` 赋值给 `self._x`,所以 `_x` 的值变为 `'blue'`。

2. 当访问 `c1.x` 时,调用的是 `__get__` 方法,这里会触发 `getX` 方法,因此打印 `'getX'` 并返回 `_x` 的值。

3. 直接访问 `c1._x` 属于对实例属性的直接访问,不通过 `Myproperty` 的描述符方法,因此不会调用 `getX`,也不会打印 `'getX'`,只是简单地返回存储在 `_x` 中的值 `'blue'`。

总结一下,`c1._x` 的访问不涉及描述符,所以不会调用 `getX`。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

鬼少 发表于 2024-10-23 21:58:42

1. 当执行 `c1.x = 'blue'` 时,调用的是 `__set__` 方法,为什么这会触发 `setX` 方法?

FishC 发表于 2024-10-23 21:58:50

鬼少 发表于 2024-10-23 21:58
1. 当执行 `c1.x = 'blue'` 时,调用的是 `__set__`...

这是因为在 `Myproperty` 描述符的 `__set__` 方法中,明确地调用了 `self.fset(instance, value)`。在您定义 `x` 这个 `Myproperty` 实例的时候,传递的 `fset` 参数就是 `setX` 方法。因此,当 `__set__` 被调用时,实际上就是在调用 `setX` 方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 关于property应用问题