Python Forum

Full Version: question about descriptor
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
hi
the below code is in :https://docs.python.org/3/howto/descriptor.html

import logging

logging.basicConfig(level=logging.INFO)

class LoggedAgeAccess:

    def __get__(self, obj, objtype=None):
        value = obj._age
        logging.info('Accessing %r giving %r', 'age', value)
        return value

    def __set__(self, obj, value):
        logging.info('Updating %r to %r', 'age', value)
        obj._age = value

class Person:

    age = LoggedAgeAccess()             # Descriptor instance

    def __init__(self, name, age):
        self.name = name                # Regular instance attribute
        self.age = age                  # Calls __set__()

    def birthday(self):
        self.age += 1                   # Calls both __get__() and __set__()
in the above code, in the last lines is written that calls _set__() and calls both __get__() and ....
why is called __set__ and __get__ ? how does it know to call them? is age in line age = LoggedAgeAccess() the same as age in __init__ method ? please give some explanation.
thanks
(Jan-07-2024, 11:54 AM)akbarza Wrote: [ -> ]how does it know to call them?
Python documentation Wrote:Any object which defines the methods __get__(), __set__(), or __delete__(). When a class attribute is a descriptor, its special binding behavior is triggered upon attribute lookup. Normally, using a.b to get, set or delete an attribute looks up the object named b in the class dictionary for a, but if b is a descriptor, the respective descriptor method gets called. Understanding descriptors is a key to a deep understanding of Python because they are the basis for many features including functions, methods, properties, class methods, static methods, and reference to super classes.
any more opinion?
(Jan-08-2024, 07:35 AM)akbarza Wrote: [ -> ]any more opinion?
I think the documentation is clear enough: Python knows how to call __get__ for example because when you write an attribute access such as spam.eggs, it looks in the dictionary of the class of the object spam and if it finds a member named eggs and this member has a __get__() method then it calls the __get__() method.
(Jan-08-2024, 10:29 PM)Gribouillis Wrote: [ -> ]
(Jan-08-2024, 07:35 AM)akbarza Wrote: [ -> ]any more opinion?
I think the documentation is clear enough: Python knows how to call __get__ for example because when you write an attribute access such as spam.eggs, it looks in the dictionary of the class of the object spam and if it finds a member named eggs and this member has a __get__() method then it calls the __get__() method.

hi
thanks for the reply
in the above code, by removing line 18, the code works again.
how does Python know that it must go to descriptor(LoggedAgeAccess) when attribute age ic called?
(Jan-09-2024, 07:00 AM)akbarza Wrote: [ -> ]in the above code, by removing line 18, the code works again.
If you remove line 18, there is no descriptor any more and __get__ or __set__ are not called. Python creates an ordinary attribute age in the dictionary of the Person instance.