我在我的基类的自定义__dir__
实现其应该返回所有用户定义__slots__
属性的列表。一般来说,这是行得通的,但它似乎在返回结果前对结果做了sort
,尽管我没有编程去实现这一点(我需要按照它们分配完全相同的顺序的属性)。定制__dir __()返回排序的属性列表按字母顺序
一个例子:
class A:
__slots__ = ['b', 'a']
def __dir__(self):
slot_attrs = []
for parent_class in reversed(type(self).__mro__[:-1]):
for attr in parent_class.__slots__:
slot_attrs.append(attr)
for attr in self.__slots__:
slot_attrs.append(attr)
return slot_attrs
class B(A):
__slots__ = ['c', 'd']
pass
class C(B):
__slots__ = []
pass
class D:
__slots__ = ['b', 'a']
def slots(self):
slot_attrs = []
for parent_class in reversed(type(self).__mro__[:-1]):
for attr in parent_class.__slots__:
slot_attrs.append(attr)
for attr in self.__slots__:
slot_attrs.append(attr)
return slot_attrs
class E(D):
__slots__ = ['c', 'd']
pass
class F(E):
pass
为slots()
和__dir__()
输出应,伊莫相同。
而是出现这种情况:
>>>c = C()
>>>f = F()
>>>print(dir(c))
['a', 'b', 'c', 'd']
>>>print(f.slots())
['b', 'a', 'c', 'd', 'c', 'd', 'c', 'd']
我可以种明白它的字母顺序排列的输出,它使用dir()
时 - 这是documented in the docs。但是,它看起来像一个错误 - 至少对我来说意想不到的行为 - 尽管我已经定义了一个自定义的方法,但它对输出进行排序。
第二个输出完全抛弃了我的游戏。这表明,dir
也使用某种过滤器,也许set
避免重复输出,因为代码是相同的,但调用slots()
返回重复值。
我既不知道为什么它首先做到这一点,也没有B)dir
究竟是在做什么。
任何指针?
编辑:
第二种情况是solved- __mro__
包含调用者的类,以及它继承了所有的类 - 因此该类包含两次。 即:
>>>F.__mro__
(<class '__main__.F'>, <class '__main__.E'>, <class '__main__.D'>, <class 'object'>)
编辑2:
情节复杂。在评论中引用的问题流下了这种行为的来源更多一点点光:
>>Couldn't __dir__ also be allowed to return a tuple?
no, because tuples are not sortable, and i don't want to
over complicate the c-side code of PyObject_Dir.
having __dir__ returning only a list is equivalent to
__repr__ returning only strings.
这似乎是一些从C源代码发起,从__dir__
被实施之前。
编辑3:
我已经打开了一个issue on python's bug tracker。让我们看看共识是什么。但是,我预计这将被放在加力燃烧器(如果有的话),因为dir()
是afaik,主要用于IDLE等的检测。
所有非独特的元素被删除,因为你不能访问在python的同名方法。 'dir'只是调用你的自定义方法,但后处理它是对文档的编译。 –
实际上,id不会将它们删除 - 我只是对它进行了测试,它也保留了它们。我只是从'F'加了'__slots__'两次。 – nlsdfnbch
它似乎仍然是意想不到的行为。如果'dir()'调用'__dir __()',那么我希望它可以像我说的那样去做,而不是在它之上做一些幕后的巫术。 – nlsdfnbch