Как help выбирает и выводит строки docstring касательно дескрипторов?

Совсем не могу понять и найти, как работает встроенная функция help в python.

Ниже приведены 3 примера (в каждом код+вывод); удивительно то, что каждый раз мы видим разный вывод функции help, применённой к экземпляру пользовательского класса.

Код.1

class Descriptor:
    'I WANT THIS DOC'

    def __init__ (self):
        self.__doc__ = 'but i got this'

    def __get__(self, inst, ownner):
        return 777

class A: data = Descriptor()

x = A()
help(x)

Вывод.1 (многое не показано для экономии места)

data = 777

Код.2

class Descriptor:
    'I WANT THIS DOC'

    def __init__ (self):
        self.__doc__ = 'but i got this'

    def __get__(self, inst, ownner):
        return inst._data            # <-- CHANGES HERE

class A: data = Descriptor()

x = A()
help(x)

Вывод.2

data
    but i got this

Код.3

class Descriptor:
    'I WANT THIS DOC'

    def __init__ (self):
        self.__doc__ = Descriptor.__doc__        # <-- CHANGES HERE

    def __get__(self, inst, ownner):
        return inst._data

class A: data = Descriptor()

x = A()
help(x)

Вывод.3

data

Думаю ситуация видна. Опишем подробнее, что наблюдаем в примере номер:

  1. __get__ возвращает конкретное значение. Кажется, что help как то понимает это, а потому решаем сразу показать нам: data = 777, игнорируя документацию (строки docstring)!!!
  2. Когда __get__ возвращает нам нечто, функция help наконец решила показать нам документацию, но правда явно прикреплённую к экземпляру дескриптора в конструкторе ('but i got this').
  3. Последний пример самый "разрывной". Мы меняем только то, что в конструкторе дескриптора присваиваем строке документации экземпляра другую строку, явно извлечённую как атрибут Descriptor, которая (строка) нормально существует к этому моменту.

Вывод, который ожидался:

1:

data
    but i got this

2:

data
    but i got this

3:

data
    I WANT THIS DOC

4 (если бы конструктора вообще не было):

data
    I WANT THIS DOC

Вопрос(ы):

Что происходит?

Почему help ведёт себя именно так в таких различных и одновременно похожих ситуациях?!

Как, вообще не передавая экземпляру дескриптора строку в конструкторе, заставить help выводить строку 'I WANT THIS DOC'? Она вообще-то — наследуемый объектом Descriptor() атрибут и если help достаёт документацию как a.__doc__ то такой атрибут есть и инициализирован! (наследование сломалось?)


Ответы (0 шт):