2009-06-19 3 views
3

Я пытаюсь изучить дескрипторы, и меня смущает поведение объектов - в двух примерах ниже, поскольку я понял __init__, они должны работать одинаково. Может кто-то развязать меня или указать мне на ресурс, который объясняет это?Разница между использованием __init__ и установкой переменной класса

import math 
class poweroftwo(object): 
    """any time this is set with an int, turns it's value to a tuple of the int 
    and the int^2""" 
    def __init__(self, value=None, name="var"): 
     self.val = (value, math.pow(value, 2)) 
     self.name = name 

    def __set__(self, obj, val): 
     print "SET" 
     self.val = (val, math.pow(val, 2)) 
    def __get__(self, obj, objecttype): 
     print "GET" 
     return self.val 

class powoftwotest(object): 
    def __init__(self, value): 
     self.x = poweroftwo(value) 

class powoftwotest_two(object): 
    x = poweroftwo(10) 


>>> a = powoftwotest_two() 
>>> b = powoftwotest(10) 
>>> a.x == b.x 
>>> GET 
>>> False #Why not true? shouldn't both a.x and b.x be instances of poweroftwo with the same values? 
+0

Возможно, вы захотите включить тип (a.x) и тип (b.x) в свой вывод. –

ответ

3

Прежде всего, назовите все классы именами LeadingUpperCase.

>>> a.x 
GET 
(10, 100.0) 
>>> b.x 
<__main__.poweroftwo object at 0x00C57D10> 
>>> type(a.x) 
GET 
<type 'tuple'> 
>>> type(b.x) 
<class '__main__.poweroftwo'> 

a.x доступ уровня экземпляра, который поддерживает дескрипторы. Это то, что подразумевается в разделе 3.4.2.2, «(так называемый класс дескриптора) появляется в словаре классов другого класса нового стиля». К классу словарь должен быть доступен экземпляр для использования методов __get__ и __set__.

b.x - это доступ на уровне класса, который не поддерживает дескрипторы.

+0

Доступ на уровне класса * может поддерживаться дескрипторами, если дескриптор находится в метаклассе. –

+0

@EthanFurman: Несмотря на то, что это абсолютно верно, это выходит за рамки этого вопроса. А также. Не так много изменений в моем ответе, не так ли? –

+0

Только последняя строка. (Вот почему я все еще проголосовал за это.) :) –