fsyscall
fsyscall

Reputation: 51

Which descriptor implementation is correct?

The following functions are listed for the Descriptor Protocol in this section of the official Python documentation.

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

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

And there is an example like that in here;

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__()

However, I can implement this example using the functions of the Descriptor definition specified in another official Python document;

import logging

logging.basicConfig(level=logging.INFO)

class LoggedAgeAccess:

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

    def __set__(self, instance, value):
        logging.info('Updating %r to %r', 'age', value)
        instance._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__()

I couldn't figure out what was different about these documents. Which document should I refer to?

Upvotes: 0

Views: 45

Answers (1)

jsbueno
jsbueno

Reputation: 110261

Both documents are correct.

The signatures are the same. The parameter names differ - but it is just that. Have in mind that Python is a dynamic typed language, and parameter names say nothing about the types that parameter should get. In your examples, obj, objtype, instance, owner are just strings as arbitrary as foo and bar.

Usually, code that create descriptors will use the instance and owner nomenclature, but that is totally up to the author, and makes no difference when running the code.

Indeed, it could make a difference if these parameters where ever called with named arguments, instead of positional arguments - but the language does not do that: descriptor methods are always called with positional arguments.

Otherwise, one of the documents would simply be incorrect, and the example would not work - and a bug against the docs should be filed. But as you noticed, both work perfectly fine.

Upvotes: 1

Related Questions