Python __dict__ 详解

Python __ dict __属性详解

我们都知道Python一切皆对象,那么Python究竟是怎么管理对象的呢?

本文转载自https://www.cnblogs.com/alvin2010/p/9102344.html

1、无处不在的__ dict __

首先看一下类的__ dict __ 属性和类对象 的__ dict __ 属性

>>> class A(object):

...     a = 0
...     b = 1

...     def __init__(self):
...             self.a = 2
...             self.b = 3

...     def test(self):
...             print("a normal func.")
...     
...     @staticmethod
...     def static_test(self):
...             print("a static func.")
...     
...     @classmethod
...     def class_test(self):
...             print("a class func.")
... 
>>> obj = A()
>>> print(A.__dict__)

{'__module__': '__main__', 'a': 0, 'b': 1, '__init__': <function A.__init__ at 0x10b5f61e0>, 'test': <function A.test at 0x10b5f6268>, 'static_test': <staticmethod object at 0x10b5f16d8>, 'class_test': <classmethod object at 0x10b5f1748>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
>>> 
>>> print(obj.__dict__)

{'a': 2, 'b': 3}

由此可见,类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类 __ dict __ 里的;

对象的 __ dict __ 中存储了一些self.xxx的一些东西;

###2、Python里什么没有__ dict __属性?

虽然说一切皆对象,但对象也有不同,一些内置的数据类型是没有 __ dict __ 属性的,如下:

>>> num = 3
>>> ll = []
>>> dd = {}
>>> print(num.__dict__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__dict__'
>>> print(ll.__dict__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
>>> print(dd.__dict__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute '__dict__'

int,list,dict等这些常用的数据类型是没有 __ dict __ 属性的,其实这是可预料的,就算给了它们dict属性也没啥用,毕竟它们只是用来做数据容器的。

3、发生继承时候的__ dict __() 属性

子类有自己的 __ dict __ ,父类也有自己的 __ dict __ ,子类的全局变量和函数放在子类的 dict 中,父类的放在父类 dict 中。

>>> class Parent(object):
...     a = 0 
...     b = 1
...     
...     def __init__(self):
...             self.a = 2
...             self.b = 3
...     def p_test(self):
...             pass
... 
>>> class Child(Parent):
...     a = 4
...     b = 5
...     
...     def __init__(self):
...             super(Child, self).__init__()
...							# self.a = 6
...							# self.b = 7
...     def c_test(self):
...             pass
...     def p_test(self):
...             pass
... 
>>> p = Parent()
>>> c = Child()
>>> 
>>> print(Parent.__dict__)
{'__module__': '__main__', 'a': 0, 'b': 1, '__init__': <function Parent.__init__ at 0x10b5f6488>, 'p_test': <function Parent.p_test at 0x10b5f6510>, '__dict__': <attribute '__dict__' of 'Parent' objects>, '__weakref__': <attribute '__weakref__' of 'Parent' objects>, '__doc__': None}
>>> 
>>> print(Child.__dict__)
{'__module__': '__main__', 'a': 4, 'b': 5, '__init__': <function Child.__init__ at 0x10b5f6598>, 'c_test': <function Child.c_test at 0x10b5f6620>, 'p_test': <function Child.p_test at 0x10b5f66a8>, '__doc__': None}
>>> 
>>> print(p.__dict__)
{'a': 2, 'b': 3}
>>> 
>>> print(c.__dict__)
{'a': 2, 'b': 3}
  1. 上段输出结果中,用红色字体标出的是类变量和函数,由结果可知,每个类的类变量、函数名都放在自己的 __ dict __ 中;
  2. 再来看下实例变量的 __ dict __ 中,父类和子类对象的 __ dict __ 是公用的。

总结:

  1. 内置的数据类型没有 __ dict __ 属性;
  2. 每个类有自己的 __ dict __ 属性,就算存着继承关系,父类的 __ dict __ 并不会影响子类的 __ dict __;
  3. 对象也有自己的 __ dict __ 属性,存储self.xxx信息,父子类对象公用 __ dict __ 。

本文转载自https://www.cnblogs.com/alvin2010/p/9102344.html

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`__slots__` 是 Python 中的一个特殊属性,它允许你显式地指定一个类的实例属性。通过使用 `__slots__`,你可以限制一个类实例可以存在的属性集合,从而优化内存使用和访问速度。 在 Python 中,每个类实例都有一个字典(`__dict__`)用于存储实例的属性。这使得你可以在运行时动态地给实例添加、修改或删除属性。然而,对于拥有大量实例的类,使用字典来存储属性可能会占用大量内存,并且属性查找会比较慢。 使用 `__slots__`,你可以预先声明一个固定的属性集合,从而避免了使用字典来存储实例的属性。通过这种方式,每个实例只会使用固定大小的内存,属性查找也变得更快。 要使用 `__slots__`,你可以在类定义中定义一个包含属性名称的元组。这些属性名称将成为实例的属性,而且除了这些属性之外,任何其他的属性都不能被添加到实例中。以下是一个示例: ```python class MyClass: __slots__ = ('attribute1', 'attribute2') def __init__(self, value1, value2): self.attribute1 = value1 self.attribute2 = value2 # 创建一个类实例 obj = MyClass(10, 20) # 访问实例属性 print(obj.attribute1) # 输出: 10 print(obj.attribute2) # 输出: 20 # 尝试添加新属性 obj.attribute3 = 30 # 抛出 AttributeError:'MyClass' object has no attribute 'attribute3' ``` 在上面的例子中,`MyClass` 类的实例只能具有 `attribute1` 和 `attribute2` 这两个属性。如果你尝试添加一个不在 `__slots__` 中的新属性,将会引发 `AttributeError` 异常。 需要注意的是,使用 `__slots__` 有一些限制和注意事项: - `__slots__` 只对当前类的实例有效,子类不受影响。 - 每个类实例仍然会有一个 `__dict__` 属性,但它只是一个空字典,不会包含实例的属性。 - 使用 `__slots__` 可能会导致一些特殊方法(例如 `__weakref__`)无法正常工作。 - 使用 `__slots__` 可能会限制动态性和灵活性。只有在确实需要优化内存和属性访问速度时才应该使用它。 希望这个解释能够帮到你!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值