为什么托管属性只适用于类属性而不适用于python中的实例属性?

时间:2009-01-09 14:38:13

标签: python attributes descriptor

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

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 __ -function?这似乎覆盖了这个功能。但为什么呢?
  2. x1中的 _v 在哪里?它不在 x1._v

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

您应该阅读thisthis

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

答案 2 :(得分:0)

我发现 _v x1 :它位于 SomeClass1 .__ dict __ ['m'] ._ v

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