问题描述:

I have a class that implements the __dir__ method. However, I am not entirely certain about some nitty gritty details of the dir API.

A: Is it really required that __dir__ returns a list? My implementation is using a set to avoid listing attributes twice, do I need to convert it to a list before returning? From the documentation I would guess it has to be a list:

If the object has a method named dir(), this method will be called

and must return the list of attributes.

However, would not returning a list break functionality at some point?


B: Does the result need to be sorted? The documentation is a bit ambiguous here:

The resulting list is sorted alphabetically.

Does this mean, calling the built-in dir automatically sorts data returned by __dir__ or does it mean dir expects sorted data from __dir__?

EDIT: Btw, my question encompasses Python 2 (2.6 and 2.7) and 3 (3.3, 3.4).

网友答案:

Under Python 2.7.3, the answers are:

A: Yes, it must be a list:

>>> 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: No, dir will sort it.

>>> class G:
...     def __dir__(self):
...             return ['c','b','a']
... 
>>> dir(G())
['a', 'b', 'c']
网友答案:

Under Python 3, you can return any sequence, including a set, and you need not sort it.

The corresponding documentation doesn't exist under Python 2, so I'm not sure what you're expected to do there.

网友答案:

In Python 2, it must be a list. Otherwise you get a TypeError when you run the dir() function on a corresponding instance.

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

d = Dirry()
dir(d)

Yields:

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

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

If returned as a list, it does not need to be sorted. The dir() function will sort for you:

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

d = DirryList()
dir(d)

Yields:

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

Even though it was not given by __dir__ in sorted order.

相关阅读:
Top