python为什么要实例化对象_python 实例化对象能够直接添加属性的意义是什么?...

Python 中自定义类的实例是可以动态添加属性的,但是内置的类的实例则不可以:

>>> class A():pass

...

>>> a = A()

>>> a.name = 'myclassA'

>>> lst = list()

>>> lst.name = 'mylst'

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'list' object has no attribute 'name'

上例中,自定义类 A 的实例 a 可以动态添加 name 属性,但 list 的实例 lst 则不可以。事实上,自定义的类若想禁止动态添加属性,则需借助 __slots__ 属性,默认情况下,自定义类是没有该属性的,比如 A 类的属性:

>>> dir(A)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

我们为自定义类 B 手动添加 __slots__ 属性,并将其值设为空:

>>> class B():

... __slots__ = {}

...

>>> b = B()

>>> b.name = 'myclassB'

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'B' object has no attribute 'name'

如上,此时 B 的实例 b 便无法像 a 一样动态添加 name 属性。

另外,对于具有 __slots__ 属性的类,该类和其实例都会缺失 __dict__ 属性,我们可以发现:实例 b 比实例 a 多了__slots__属性,而实例 a 要比实例 b 多了__dict__和 name 属性:

>>> dir(a)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']

>>> dir(b)

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__']

>>> b.__dict__

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'B' object has no attribute '__dict__'

>>> a.__dict__

{'name': 'myclassA'}

>>> b.__slots__

{}

>>> a.__slots__

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'A' object has no attribute '__slots__'

此外,__slot__的值若为非空,则类的实例只能添加__slots__值中定义的属性,而不能添加其他属性:

>>> class C():

... __slots__ = {'name'}

...

>>> c = C()

>>> c.name = 'MyclassC'

>>> c.other = 'dobi'

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'C' object has no attribute 'other'

>>> c.__slots__

{'name'}

如上,自定义类 C 的实例 c 只能添加 name 属性,而不能添加 other 属性;另外,即便可以添加 name 属性,C 类和 c 仍无 __dict__ 属性,不过类 C 类可以动态的添加'__dict__' 属性,但实例 c 不可以:

>>> c.__dict__

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'C' object has no attribute '__dict__'

>>> C.__dict__

mappingproxy({'__doc__': None, '__module__': '__main__', 'name': , '__slots__': {'name'}})

因为 c 是基于 C 类创建,而 C 类则是基于其超类创建,而 C 类的超类默认是没有定义__slots__的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值