views:

132

answers:

1

I'm trying to learn descriptors, and I'm confused by objects behaviour - in the two examples below, as I understood __init__ they should work the same. Can someone unconfuse me, or point me to a resource that explains this?

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?
+2  A: 

First, please name all classes with LeadingUpperCaseNames.

>>> 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 is instance-level access, which supports descriptors. This is what is meant in section 3.4.2.2 by "(a so-called descriptor class) appears in the class dictionary of another new-style class". The class dictionary must be accessed by an instance to use the __get__ and __set__ methods.

b.x is class-level access, which does not support descriptors.

S.Lott