类和对象-Ⅶ
>>> # 私有变量>>> class C:
... def __init__(self, x ):
... self._x = x
...
>>>
>>> class C:
... def __init__(self, x ):
... self.__x = x
... def set_x(self, x):
... self.__x = x
... def get_x(self):
... print(self.__x)
...
>>> c = C(50)
>>> c.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'x'
>>> c.get_x()
50
>>> c.set_x(11)
>>> c.get_x()
11
>>> # 想要访问变量的值,就需要使用指定的接口,比如这段代码中的 set_x() 和 get_x() 方法
>>> c.__dict__
{'_C__x': 11}
>>> c._C__x
11
>>> # 方法名也是同样的道理:
>>> class D:
... def __func(self):
... print("Hello FishC")
...
>>> d = D()
>>> d.__func()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'D' object has no attribute '__func'
>>> d._D__func()
Hello FishC
>>> # 效率提升之道
>>> # Python 对象存储属性的工作原理 —— 字典(__dict__):
>>> class C:
... def __init__(self, x):
... self.x = x
...
>>> c = C(250)
>>> c.x
250
>>> c.__dict__
{'x': 250}
>>> # 对象动态添加属性,就是将键值对添加到 __dict__ 中:
>>> c.y = 2023
>>> c.__dict__
{'x': 250, 'y': 2023}
>>> # 直接通过给字典添加键值对的形式来创建对象的属性:
>>> c.__dict__['z'] = 66
>>> c.__dict__
{'x': 250, 'y': 2023, 'z': 66}
>>> # 字典高效率的背后是以付出更多存储空间为代价的
>>> # Python 专门设计了一个 __slots__ 类属性,避免了利用字典存放属性造成空间上的浪费。
>>> class C:
... __slots__ = ['x', 'y']
... def __init__(self, x):
... self.x = x
...
>>> c = C(250)
>>> # 这样,我们就创建了一个属性受限制的对象。
>>> c.x
250
>>> c.y = 500
>>> c.y
500
>>> # 如果想要动态地添加一个属性,那就不好意思了:
>>> c.z = 99
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'z'
>>> # 这种限制不仅体现在动态添加属性上,如果在类的内部,想创建一个 __slots__ 不包含的属性,也是不被允许的:
>>> class D:
... __slots__ = ['x', 'y']
... def __init__(self, x, y z):
File "<stdin>", line 3
def __init__(self, x, y z):
^
SyntaxError: invalid syntax
>>> c.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__dict__'
>>> # 因为使用了 __slots__ 属性,那么对象就会划分一个固定大小的空间来存放指定的属性,这时候 __dict__ 属性就不需要了,空间也就节约了出来。
>>> # 继承自父类的 __slots__ 属性是不会在子类中生效的,Python 只关注各个具体的类中定义的 __slots__ 属性:
>>> class E(C):
... pass
...
>>> e = E(250)
>>> e.x
250
>>> e.y = 520
>>> e.z = 666
>>> e.__slots__
['x', 'y']
>>> e.__dict__
{'z': 666}
>>> # 对象 e 虽然拥有 __slots__ 属性,但它同时也拥有 __dict__ 属性: {:7_146:}{:7_146:}
页:
[1]