英文:
Why aren't __mro__ and mro listed in the dir() of a class object
问题
如果mro
和__mro__
是C
的有效属性,为什么它们不会显示在dir()
函数的输出中呢?
我已经看过了这个帖子,其中接受的答案说这是因为__mro__
和mro
是C
的元类type
的属性,type
是C
的元类(这意味着C
的类object
是type
的一个实例),而不是C
的超类,因此type
的__dict__
属性不会与dir(C)
的结果连接在一起。我仍然认为C
作为type
的一个实例不应该导致type
的属性__mro__
不会被列在dir(C)
中。为了说明这一点,考虑以下代码:
class Sample:
a = 5
def f():
pass
s = Sample()
print(dir(s)) # 输出:太长了
print("f" in dir(s)) # 输出:True
print("a" in dir(s)) # 输出:True
正如你所看到的,Sample
不是s
的超类,而是s
的类型,这意味着s
是Sample
的一个实例,这与前面代码示例中的C
与type
的关系相同。如你所见,Sample
的属性在dir(s)
中列出。因此,按照这个逻辑,我希望type
的属性也会在dir(C)
中列出,但正如我们之前看到的那样,__mro__
和mro
被省略了。
有人能够解释这是为什么吗?
英文:
Consider this piece of code:
class C:
pass
print(C.mro()) # Output: [<class '__main__.C'>, <class 'object'>]
print(C.__mro__) # Output: (<class '__main__.C'>, <class 'object'>)
print(dir(C)) # Output: too long :(
print("__mro__" in dir(C) or "mro" in dir(C)) # Output: False
If mro
and __mro__
are valid attributes of C
, why don't they show up in the dir()
function's output?
I have already seen this post and the accepted answer says it's because __mro__
and mro
are attributes of type
which is the metaclass of C
(meaning C
's class object
is an instance of type
) and not its superclass so type
's __dict__
attribute isn't concatenated with the result of dir(C)
. I still don't think C
being an instance of type
should cause type
's attribute __mro__
to not be listed in dir(C)
. To illustrate this, consider the following code:
class Sample:
a = 5
def f():
pass
s = Sample()
print(dir(s)) # Output: too long
print("f" in dir(s)) # Output: True
print("a" in dir(s)) # Output: True
As you can see, Sample
isn't s
's superclass, it's s
's type, so to speak, meaning s
is an instance of Sample
which is the same relationship that C
from the previous code sample had to type
. As you can see, the attributes of Sample
are listed in dir(s)
. So by this logic I would expect the attributes of type
to also be listed in dir(C)
but as we saw previously __mro__
and mro
are left out.
Can anybody shed some light on why this is?
答案1
得分: 1
dir(obj)
只是调用了 obj.__dir__
。对于大多数对象,这将调用 object.__dir__
,它会从 __dict__
和对象的类型中收集属性。
type.__dir__
(这是在调用 dir(C)
或 dir(Sample)
时所调用的内容)恰好不会收集类的类型上的属性(该类型将是 type
或类所具有的任何元类)。
如果你调用类的“常规” __dir__
,你可以看到 mro
/__mro__
:
class C: pass
object.__dir__(C) # => [..., '__mro__', ..., 'mro', ...]
class TypeWithoutDir(type): __dir__ = object.__dir__
class D(metaclass=TypeWithoutDir): pass
dir(D) # => [..., '__mro__', ..., 'mro', ...]
英文:
dir(obj)
just calls obj.__dir__
. For most objects, this will call object.__dir__
, which collects attributes from __dict__
and the type of the object.
type.__dir__
(Which is what is called when you call dir(C)
or dir(Sample)
) just happens to not collect attributes on the type of class (which will be type
or whatever metaclass the class had).
If you call the "regular" __dir__
on your class, you can see mro
/__mro__
:
class C: pass
object.__dir__(C) # => [..., '__mro__', ..., 'mro', ...]
class TypeWithoutDir(type): __dir__ = object.__dir__
class D(metaclass=TypeWithoutDir): pass
dir(D) # => [..., '__mro__', ..., 'mro', ...]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论