gpt4 book ai didi

python - 当我使用 dir([user-defined object]) 时,为什么它还会返回对象父类的命名空间中的名称?

转载 作者:行者123 更新时间:2023-12-04 17:01:17 24 4
gpt4 key购买 nike

dir() 函数,如果没有给定参数,则返回当前局部作用域中的名称列表。但是,如果我们给出参数,它会返回给定对象参数的属性命名空间内的名称(即对象的属性)。知道了这一点,请考虑以下类:

>>> class Foo():

classVar=23

def __init__(self,x):
print("dir in init:",dir())
self.x=x

def getx(self):
return self.x
当我打电话时 dir(Foo) ,它返回在类对象 Foo 中定义的名称列表(即 Foo 的属性列表),如下所示:
>>> dir(Foo)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'classVar', 'getx']
如果我执行以下操作:
>>> newFoo=Foo(17)
dir in init: ['self', 'x'] #list of names in the local variable namespace from the __init__ method call.
>>> dir(newFoo) #called from the global scope
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'classVar', 'getx', 'x']

我们可以看到 newFoo 的属性列表(在 newFoo 的属性命名空间中定义的名称)还包括在其父类中定义的名称,例如 getx ,和 classVar .我想也许 dir()不仅返回本地命名空间,还返回封闭的命名空间。我使用一个函数对此进行了测试,但它只返回本地命名空间内的名称,而不返回封闭命名空间内的名称。我想知道为什么用户定义的类/对象会出现这种情况。当我无法使用 dir() 访问函数调用中的封闭命名空间时,为什么我还能够看到父类命名空间中的名称? ?

最佳答案

类的命名空间不包含其实例的命名空间。实际上,对象的属性访问obj.attr经历了不同的阶段:

  • 检查是否有 data descriptor命名 attr存在于 method resolution order对象类型:type(obj).mro() .
  • 检查是否"attr"存在于 obj.__dict__ .
  • 检查是否attr MRO 中另有规定。
  • 最后,如果以上都没有成功和 __getattr__ 被定义,它将被调用 "attr"作为论据。

  • 以上步骤由 object.__getattribute__ 处理可以在自定义类中覆盖。
    另请注意,类型可以自由自定义 dir(obj) 返回的内容。通过定义 __dir__ .
    同样重要的是要注意,没有包含例如的类范围类定义中的函数定义(参见 Python Scopes and Namespaces)。从以下示例中可以看出,这是一个常见的陷阱:
    >>> class Test:
    ... x = 1
    ... y = [i*x for i in range(5)]
    ...
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 3, in Test
    File "<stdin>", line 3, in <listcomp>
    NameError: name 'x' is not defined
    这里列表推导式定义了它自己的范围并尝试解析名称 x根据 LEGB rule (其中“E”代表“封闭”)。但是,由于类定义不是正确的范围,因此无法在名称解析期间进行搜索。

    关于python - 当我使用 dir([user-defined object]) 时,为什么它还会返回对象父类的命名空间中的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63705028/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com