Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a descriptor __get__ have access to the object's type but __set__ does not?

Tags:

From https://docs.python.org/2/howto/descriptor.html:

descr.__get__(self, obj, type=None) --> value

descr.__set__(self, obj, value) --> None

descr.__delete__(self, obj) --> None

Why does the __get__ method get access to type but the other two don't?

like image 540
Jason S Avatar asked Nov 04 '17 19:11

Jason S


1 Answers

In __get__ the type argument is a class name, which is helpful, when accessing an attribute through a class, because in this case obj (instance) will be None. In __set__ you don't need type argument, because it's not possible to set value of a descriptor through a class, you will just overwrite a descriptor with new value.

Consider following code

class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating', self.name
        self.val = val

>>> class MyClass(object):
...     x = RevealAccess(10, 'var "x"')
...     y = 5
...
>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> MyClass.x  # accessing descriptor x through class
Retrieving var "x"
20
>>> MyClass.x = 20  # class parameter x is overwritten with value 20, it's not a descriptor any more
>>>
like image 149
Shmygol Avatar answered Sep 22 '22 12:09

Shmygol