Почему cls .__ name__ не появляется в dir ()?

python

871 просмотра

3 ответа

Допустим, у меня есть простой класс:

class Foobar(object):
    pass

Если я использую dir(Foobar), я получу следующий вывод:

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

Даже если он не отображается в выходных данных dir(), я могу получить доступ к __name__:

Foobar.__name__

и получить Foobar.

Почему Python ведет себя так?

Автор: Fabian Источник Размещён: 12.11.2019 09:51

Ответы (3)


8 плюса

Решение

dirне гарантируется возвращение всех возможных атрибутов. Из документов :

Поскольку dir () предоставляется в первую очередь для удобства использования в интерактивном приглашении, он пытается предоставить интересный набор имен больше, чем пытается предоставить строго или согласованно определенный набор имен, и его подробное поведение может изменяться в разных выпусках. Например, атрибуты метакласса отсутствуют в списке результатов, когда аргумент является классом.

Автор: unutbu Размещён: 17.08.2011 04:26

3 плюса

Согласно документации python о методе dir () , вы можете реализовать метод __dir __ () для вашего объекта, который возвращает список элементов, которые вы хотите видеть при вызове dir для вашего объекта.

Член __name__ является частью некоторых специальных атрибутов объектов python и, как сказано в документации:

Некоторые из них не сообщаются встроенной функцией dir ().

Автор: Cédric Julien Размещён: 17.08.2011 04:27

2 плюса

Ответы на недавний обман этого вопроса привели меня к тому, что мне хотелось бы уточнить этот ответ немного подробнее. Во-первых, принятый ответ правильный. dirпросто вызывает __dir__метод ловушки, а метод ловушки по умолчанию __dir__обычно просто возвращает ключи объекта __dict__.

Во-вторых, __name__не входит object.__dict__и не помещается в __dict__подклассы. Если его нет __dict__, где он находится и как его искать?

Как я понимаю, исходный код , есть ряд дескрипторов, которые устанавливаются typeпри создании класса. Один из этих дескрипторов есть __name__. __name__Геттер называет type_name и связующий называет type_set_name . Эти методы получения / установки фактически получают / устанавливают имя в tp_nameслоте экземпляра объекта типа (т.е. класса). Так как это на самом деле специальный слот для объекта типа, он на самом деле не живет в классе __dict__и, следовательно, не получает сообщения varsили dir.

Обратите внимание, что dirдля экземпляров объектов типа (т. Е. Классов), в частности, не добавляются члены из __class__атрибута from, поскольку «методы, принадлежащие метаклассу, вероятно, будут более запутанными, чем полезными» .

Итак, давайте соберем все это вместе.

  • objectне имеет __name__атрибута, но typeимеет.
  • type«S __name__атрибут на самом деле является дескриптором.
  • Так как object«метаклассом сек является type, когда object.__name__запрашивается, type» s __name__дескриптор вызывается.
  • nameДескриптор ищет имя в type->tp_nameслоте. type->tp_nameСлот заполняется type.__new__при создании класса.
  • object.__dir__специально написано, чтобы не сообщать о свойствах метакласса класса, так как разработчики Python считают, что это принесет больше вреда, чем пользы.
Автор: mgilson Размещён: 11.08.2017 12:42
Вопросы из категории :
32x32