Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在dir(MyClass)中没有出现mro?_Python_Method Resolution Order - Fatal编程技术网

Python 为什么在dir(MyClass)中没有出现mro?

Python 为什么在dir(MyClass)中没有出现mro?,python,method-resolution-order,Python,Method Resolution Order,输出: class MyClass(object): pass print MyClass.__mro__ print dir(MyClass) (,) “UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU

输出:

class MyClass(object):
    pass

print MyClass.__mro__
print dir(MyClass)
(,)
“UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU u'、uuu str_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

为什么Python文档中的
\uu mro\uuu
没有与
dir()一起列出?

因为提供dir()主要是为了方便在 交互式提示,它尝试提供一组有趣的名称 不仅仅是试图提供一个严格或一致定义的集合 其详细行为可能会随着版本的不同而变化。对于 例如,当 论点是一个类


\uuuumro\uuuuuu
是一个只读属性,用于在类从多个基类继承时确定方法解析。如果希望自定义此行为,则应使用元类(一种特殊类型的对象,其目的是创建类实例),该元类重写
mro()
方法<代码>\uuuMRO\uuuuuuuuuu
在任何情况下都保持不变。

我最近也在想同样的事情。我在寻找一个更符合“Python的实现如何导致
mro
/
\uuuuu mro\uuuuuu
不被列在
dir
中?”的答案,而不仅仅是“Python的文档如何证明
mro
不被列在
dir
中?”我不喜欢当我对编程语言行为的期望与它的实际行为不匹配时,因为这意味着我对该语言的理解是错误的——除非它只是一个类似
urllib2.escape
的bug。所以我四处搜寻,直到找到答案

上面评论中引用的文档中的adolfopa行很好地解释了dir的行为

如果对象是类型或类对象,则列表包含其属性的名称,并递归地包含其基的属性的名称

这是什么意思
dir
递归地从类的
\uuu dict\uuu
及其每个超类的
\uu dict\uu
收集属性

(<class '__main__.MyClass'>, <type 'object'>)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
之所以
dir(object)
没有列出
\uuumro\uuuu
/
mro
,是因为它们不是object的属性。它们是
类型的属性。每一个没有定义自己的
\uuuu元类的类都是
类型的实例。大多数元类都是子类
type
。此类元类的实例也是类型的实例<代码>MyClass.\uuuMRO\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

Python实现类的方式必然会对dir的工作方式产生轻微的异常

通常,
dir(MyClass)==dir(MyClass(*requiredparameters))#True

然而,
dir(type)==dir(type(*requiredparameters))#False
,但唯一可能的方法是如果
type.uu dict_u
dir
是相同的。这显然不是
dir
的目的

但是等等
dir
是通过递归求和创建的,为什么我们不能改变它的最后一部分,使
dir(object)
不再只是
对象。
而是成为
对象。
。这样,它将具有
mro
/
\uuuuuuuuuuuuuuuuuuuuuu
以及类对象具有的所有其他属性?啊,但是这些将是类对象的属性,而不是类。那么,有什么区别呢

考虑

set(dir(object)) == set(dict(object.__dict__).keys() #True



class A(object):
    ...

class B(object):
    ...

class C(B):
    ...

class D(C,A):
    ...

set(dir(D)) == set(D.__dict__.keys()) + set(C.__dict__.keys()) \
   + set(B.__dict__.keys()) + set(A.__dict__.keys()) \
   + set(object.__dict__.keys()) #True
list.uu mro_uuu#(,)
鉴于

list.__mro__ #(<type 'list'>, <type 'object'>)
[]。\uuu mro__
#回溯(最近一次呼叫最后一次):
#文件“”,第1行,在
#AttributeError:'list'对象没有属性'\uuuMRO''
现在,我们可以很好地回答我们可以依靠
dir
列出什么,以及我们可以依靠
dir
不列出什么。简单的答案就是我们已经讨论过的答案。它以递归方式列出类的
\uuuuu dict\uuu
中的所有键,以及每个超类的
\uuuu dict\uuu
中的所有键。对于一个实例,它还包括该实例的
\uuuu dict\uuuu
中的所有参数。要填充负数空间,它不会列出
\uuuuuuGetAttr\uuuuuuuuuuu
中定义的任何内容,或者
\uuuuuuuuuuGetAttribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
中定义的任何内容(如果它不在
目录中)。它也没有列出类型/元类型的任何属性


我觉得我应该指出的另一件事是:丹的答案,在我写这篇文章时是公认的答案,包含的信息是不准确的,或者至少是误导性的

无法设置内置对象的属性,因此在某种意义上,
type.\uuuumro\uuuuu
是“只读”的,但其方式与
list.append
是或
type.mro
是相同的

MyClass.\uu mro\uu=“Hello world!”
不会导致错误。它不会影响
类型中定义的方法解析顺序。因此,如果您试图修改该行为,它可能不会产生您预期的效果。(它所做的是使
MyClass(*requiredparameters)。\uuuumro\uuuu
成为
“Hello World!”
,这本应该是您所期望的,因为在python中定义类的属性就是这样工作的。)您还可以在对类型进行子分类以创建元类时重写
\umro\uu
。如果您不重写它,它将被继承,就像您不重写的任何其他内容一样。(如果您创建的元类不是类型的子类,也不是返回类型实例的函数,那么您可能已经非常清楚自己在做什么,因此不必担心这一点,但是__<
[].__mro__
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# AttributeError: 'list' object has no attribute '__mro__'