我在我的基類的自定義__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