Реализация `__dir__` в Python: нужно ли возвращать список и нужно ли сортировать список?

У меня есть класс, реализующий метод __dir__. Однако я не совсем уверен в некоторых деталях dir API.

A: Действительно ли требуется, чтобы __dir__ возвращал список? В моей реализации используется set, чтобы избежать двойного перечисления атрибутов, нужно ли мне преобразовать его в список перед возвратом? Из документации я бы предположил, что это должен быть список:

Если у объекта есть метод с именем dir(), этот метод будет вызван и должен вернуть список атрибутов.

Однако не будет ли в какой-то момент возвращаться функция разрыва списка?


B: Нужно ли сортировать результат? Документация здесь немного двусмысленна:

Полученный список сортируется по алфавиту.

Означает ли это, что вызов встроенного dir автоматически сортирует данные, возвращаемые __dir__, или это означает, что dir ожидает отсортированные данные от __dir__?

РЕДАКТИРОВАТЬ: Кстати, мой вопрос касается Python 2 (2.6 и 2.7) и 3 (3.3, 3.4).


person SmCaterpillar    schedule 01.04.2015    source источник


Ответы (3)


В Python 2.7.3 ответы таковы:

A: Да, это должен быть список:

>>> class F:
...     def __dir__(self):
...             return set(['1'])
... 
>>> dir(F())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __dir__() must return a list, not set

B: Нет, dir разберется.

>>> class G:
...     def __dir__(self):
...             return ['c','b','a']
... 
>>> dir(G())
['a', 'b', 'c']
person Dan D.    schedule 01.04.2015

В Python 3 можно вернуть любую последовательность, включая набор , и вам не нужно его сортировать.

Соответствующая документация не существует для Python 2, поэтому я не уверен, что вы там должны делать.

person Kevin    schedule 01.04.2015

В Python 2 это должен быть list. В противном случае вы получите TypeError при запуске функции dir() в соответствующем экземпляре.

class Dirry(object):
    def __dir__(self):
        return set('andy pandy mandy sandy'.split())

d = Dirry()
dir(d)

Урожайность:

      5 d = Dirry()
----> 6 dir(d)

TypeError: __dir__() must return a list, not set

Если возвращается в виде списка, его не нужно сортировать. Функция dir() отсортирует для вас:

class DirryList(object):
    def __dir__(self):
        return 'andy pandy mandy sandy'.split()

d = DirryList()
dir(d)

Урожайность:

['andy', 'mandy', 'pandy', 'sandy']

Несмотря на то, что __dir__ не отсортировал его по порядку.

person Jonathan Eunice    schedule 01.04.2015