2

为了说明问题,请检查以下代码:

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return self._v
  def __set__(self, obj, value):
    self._v = value
    print "set", self, obj, value
    return None

class SomeClass1(object):
  m = MyDescriptor()

class SomeClass2(object):
  def __init__(self):
    self.m = MyDescriptor()

x1 = SomeClass1()
x2 = SomeClass2()

x1.m = 1000
# ->  set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000
x2.m = 1000 # I guess that this overwrites the function. But why?
# ->
print x1.m
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000
print x2.m
# -> 10000
  1. 为什么x2.m = 1000不调用__set__ -函数?似乎这会覆盖该功能。但为什么?
  2. x1中的_v在哪里?它不在x1._v中
4

3 回答 3

3

回答你的第二个问题,在哪里_v

您的描述符版本保留_v在描述符本身中。描述符的每个实例(类级实例SomeClass1,以及类对象中的所有对象级实例都SomeClass2将具有不同的_v.

看看这个版本。此版本更新与描述符关联的对象。这意味着对象(SomeClass1x2)将包含该属性_v

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return obj._v
  def __set__(self, obj, value):
    obj._v = value
    print "set", self, obj, value
于 2009-01-09T14:55:59.717 回答
3

你应该阅读这个这个

它覆盖了该函数,因为您没有重载 SomeClass 的__set__and__get__函数,而是 MyDescriptor 类的函数。也许您希望 SomeClass 继承 MyDescriptor?SomeClass1 打印“get”和“set”输出,因为它是一个静态方法 AFAIK。有关详细信息,请阅读上面的链接。

于 2009-01-09T15:11:27.893 回答
0

我找到了x1的_v:它在SomeClass1.__dict__['m']._v

对于 S.Lott 在另一个答案中建议的版本:_vx1._v

于 2009-01-10T18:17:28.203 回答