2009-01-09 78 views
2

为了说明问题,请检查下面的代码:为什么托管属性只适用于类属性,而不适用于python中的实例属性?

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. _v in x1?这不是在x1._v

回答

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 
+0

谢谢,这是一个好主意实施。 _v的一个问题:我也无法通过“MyDescriptor._v”访问它 - 这很明显,因为它不是MyDescriptor的类属性。但是实例的显式名称是什么?它应该以某种方式访问​​,对吧? – 2009-01-09 15:12:32

3

你应该阅读thisthis

它overwri测试函数是因为您没有重载SomeClass的__set____get__函数,而是MyDescriptor类的函数。也许你想让SomeClass继承MyDescriptor? SomeClass1打印“get”和“set”输出,因为它是静态方法AFAIK。详情请阅读上面的链接。

0

我发现X1_v:它是在SomeClass1 .__的dict __ [ 'M'] ._ v

对于其它应答内由美国洛特建议的版本:_v是在x1._v

相关问题