当前位置: 首页 > 面试题库 >

python中dir和__dict__之间的最大区别是什么

董凡
2023-03-14
问题内容
class C(object):
    def f(self):
        print self.__dict__
        print dir(self)
c = C()
c.f()

输出:

{}

['__class__', '__delattr__','f',....]

为什么自我中不存在“ f”。dict


问题答案:

dir() 不仅仅是查找 __dict__

首先,dir()是一种API方法,它知道如何使用属性__dict__来查找对象的属性。

但是,并非所有对象都具有__dict__属性。例如,如果要向自定义类添加__slots__属性,则该类的实例将没有__dict__属性,但dir()仍可以列出这些实例上的可用属性:

>>> class Foo(object):
...     __slots__ = ('bar',)
...     bar = 'spam'
... 
>>> Foo().__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__dict__'
>>> dir(Foo())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar']

同样适用于许多内置类型。list没有__dict__属性,但是您仍然可以使用列出所有属性dir()

>>> [].__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

dir()实例有什么用

Python实例具有自己的__dict__,但它们的类也有:

>>> class Foo(object):
...     bar = 'spam'
... 
>>> Foo().__dict__
{}
>>> Foo.__dict__.items()
[('__dict__', <attribute '__dict__' of 'Foo' objects>), ('__weakref__', <attribute '__weakref__' of 'Foo' objects>), ('__module__', '__main__'), ('bar', 'spam'), ('__doc__', None)]

dir()方法使用 两种 这些__dict__属性, 并且 一来就object上创建实例,类可用属性的完整列表,并在类的所有祖先。

在类上设置属性时,实例也会看到以下内容:

>>> f = Foo()
>>> f.ham
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'ham'
>>> Foo.ham = 'eggs'
>>> f.ham
'eggs'

因为该属性已添加到类中__dict__

>>> Foo.__dict__['ham']
'eggs'
>>> f.__dict__
{}

注意实例如何__dict__留空。在Python对象上进行属性查找遵循对象的层次结构,从实例到类型,再到父类,以搜索属性。

仅当直接在实例上设置属性时,您才可以在实例保持不变__dict__的情况下看到反映在实例中的属性__dict__

>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False

TLDR;或摘要

dir()不仅查找对象__dict__(有时甚至不存在),它还将使用对象的遗产(其类或类型,以及该类或类型的任何超类或父级)为您提供完整的图像所有可用的属性。

实例__dict__只是该实例上的“本地”属性集,并不包含该实例上可用的每个属性。相反,您还需要查看类和类的继承树。



 类似资料:
  • 问题内容: 有没有之间的差异,并在Python? (我希望会有区别,因为否则会破坏“一种方法”的原则… :) 问题答案: Python对象将其实例变量存储在属于该对象的字典中。返回此字典(与一样)。另一方面,返回的字典,其中包含“属性,其类的属性以及递归其类的基类的属性”。 当您使用点运算符访问对象的属性时,python所做的不仅仅是在该对象字典中查找该属性。一个常见的情况是when是类的对象,您

  • 本文向大家介绍python中dir()与__dict__属性的区别浅析,包括了python中dir()与__dict__属性的区别浅析的使用技巧和注意事项,需要的朋友参考一下 前言 只要是有属性的数据对象(不一定是面向对象的对象实例,而是指具有数据类型的数据对象),都可以通过__dict__和dir()来显示数据对象的相关属性。 __dict__可以看作是数据对象的名称空间,所以只包含自己的属性,

  • 本文向大家介绍基于Python __dict__与dir()的区别详解,包括了基于Python __dict__与dir()的区别详解的使用技巧和注意事项,需要的朋友参考一下 Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案。 __dict__与dir()的区别: dir()是一个函数,返回的是list; __dict__是一个字典,键为

  • 问题内容: 以下两个查询给出完全不同的结果的原因是什么? 我已经在Google周围搜索了反引号和撇号(又称为单引号)之间的区别,但是我找不到任何迹象表明为什么对于像上列这样的列名它们会有不同的解释。 难道实际上不是将后一个查询中的单引号字符串解释为列名,而是解释为任意字符串文字,可以说其为“ 1”吗?如果是这样,要找到任何有关撇号含义的页面并不容易。 问题答案: “价格”(撇号或引号)是一个字符串

  • 发送消息1、2、3、4 接收消息1、2、3、4 崩溃/断开连接 发送消息5、6、7 对于这种结果,我必须使用哪个值,以及其他更改/配置需要做什么

  • 在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM以前在这里保存它的类。在Java 8中,它被移除并被称为元空间的区域所取代。 PermGen和Metaspace之间最重要的区别是什么? 我知道的唯一区别是,并且忽略了VM参数。