Ответ 1
dir
вызывает __dir__
внутренне:
In [1]: class Hello():
...: def __dir__(self):
...: return [1,2,3]
...:
In [2]: dir(Hello())
Out[2]: [1, 2, 3]
в python какая разница между функцией dir()
и атрибутом __dir__
в python?
>>> 2 .__dir__()
['__divmod__', 'real', '__rxor__', '__floor__', '__hash__', '__index__', '__lt__', '__ceil__', '__repr__', '__reduce_ex__', '__rpow__', '__rand__', '__truediv__', '__subclasshook__', '__doc__', '__radd__', '__or__', '__pow__', '__trunc__', '__rrshift__', '__delattr__', '__reduce__', '__rlshift__', 'conjugate', '__xor__', '__rtruediv__', '__rfloordiv__', '__ge__', '__setattr__', '__class__', 'bit_length', '__neg__', '__mod__', '__int__', '__pos__', 'from_bytes', '__format__', '__rmul__', '__lshift__', '__rsub__', '__new__', '__add__', '__floordiv__', 'imag', 'to_bytes', 'numerator', '__dir__', '__abs__', '__init__', '__sizeof__', '__getnewargs__', '__getattribute__', '__invert__', '__gt__', '__rshift__', '__ne__', '__rdivmod__', '__mul__', '__and__', '__sub__', '__rmod__', '__round__', '__ror__', '__le__', '__eq__', '__float__', '__bool__', '__str__', 'denominator']
>>> dir(2)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
dir
вызывает __dir__
внутренне:
In [1]: class Hello():
...: def __dir__(self):
...: return [1,2,3]
...:
In [2]: dir(Hello())
Out[2]: [1, 2, 3]
Документы объясняют это:
Если у объекта есть метод с именем __dir __(), этот метод будет вызван и должен вернуть список атрибутов. Это позволяет объектам, которые реализуют пользовательскую функцию __getattr __() или __getattribute __(), настраивать способ, которым dir() сообщает свои атрибуты.
Если объект не предоставляет __dir __(), функция старается собрать информацию из атрибута __dict__ объектов, если он определен, и из объекта своего типа. Результирующий список не обязательно является полным и может быть неточным, если объект имеет собственный __getattr __().
dir вызывает метод __dir__
, если он присутствует,
из документация python:
dir ([object]) ¶ Без аргументов верните список имен в текущий локальный охват. С аргументом попытайтесь вернуть список действительные атрибуты для этого объекта.
Если объект имеет метод с именем
__dir__()
, этот метод будет вызываться и должен возвращать список атрибутов. Это позволяет объектам, которые реализовать пользовательскую функцию__getattr__()
или__getattribute__()
для настроить способdir()
сообщить свои атрибуты.Если объект не предоставляет
__dir__()
, функция пытается изо всех сил для сбора информации из атрибута__dict__
объектов, если и от объекта своего типа. Полученный список не обязательно завершена и может быть неточной, когда объект имеет пользовательский__getattr__()
.
Стоит отметить, что __dir__
для многих объектов нельзя настроить, поэтому, если вы вызываете его напрямую, нет возможности разместить там прокладку/обертку.
Легко заменить встроенный dir
и дать ему некоторые специальные полномочия, если вам нужно. Трюки, подобные этому, могут быть очень полезны при отладке.