【问题标题】:Implementing `__dir__` in Python: Does it need to return a list and does the list need to be sorted?在Python中实现`__dir__`:是否需要返回一个列表,列表是否需要排序?
【发布时间】:2015-04-01 14:30:35
【问题描述】:

我有一个实现__dir__ 方法的类。但是,我并不完全确定 dir API 的一些细节。

A__dir__ 真的需要返回一个列表吗?我的实现是使用set 来避免两次列出属性,我是否需要在返回之前将其转换为列表?从documentation 我猜它必须是一个列表:

如果对象有一个名为dir()的方法,这个方法会被调用 并且必须返回属性列表。

但是,在某些时候不会返回列表中断功能吗?


B:结果需要排序吗?这里的文档有点模棱两可:

结果列表按字母顺序排序。

这是否意味着,调用内置的dir 会自动对__dir__ 返回的数据进行排序,还是意味着dir 期望来自__dir__ 的排序数据?

编辑:顺便说一句,我的问题包括 Python 2(2.6 和 2.7)和 3(3.3、3.4)。

【问题讨论】:

    标签: python built-in


    【解决方案1】:

    在 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']
    

    【讨论】:

      【解决方案2】:

      Python 3下,you can return any sequence,包含一个集合,不需要排序。

      在 Python 2 下不存在相应的文档,所以我不确定你应该在那里做什么。

      【讨论】:

        【解决方案3】:

        在 Python 2 中,它必须是 list。否则,当您在相应实例上运行 dir() 函数时,您会得到 TypeError

        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__ 没有按排序顺序给出。

        【讨论】:

          猜你喜欢
          • 2011-02-13
          • 1970-01-01
          • 2018-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-28
          • 1970-01-01
          相关资源
          最近更新 更多