网站建设合同中英文,网站建设 网站优化,如何做汽车团购网站,网站备案包括哪些1.私有变量
在大多数面向对象的编程语言中#xff0c;都存在着私有变量#xff08;private variable#xff09;的概念#xff0c;所谓私有变量#xff0c;就是指通过某种手段#xff0c;使得对象中的属性或方法无法被外部所访问。
Python 对于私有变量的实现是引入了一…1.私有变量
在大多数面向对象的编程语言中都存在着私有变量private variable的概念所谓私有变量就是指通过某种手段使得对象中的属性或方法无法被外部所访问。
Python 对于私有变量的实现是引入了一种叫 name mangling 的机制翻译过来叫 “名字改编”、“名称改写” 或者 “名称修饰”语法是在变量名前面加上两个连续下划线__ 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(250)此时我们是无法直接通过变量名访问到该变量的 c.__x
Traceback (most recent call last):File pyshell#13, line 1, in modulec.__x
AttributeError: C object has no attribute __x想要访问变量的值就需要使用指定的接口比如这段代码中的 set_x() 和 get_x() 方法 c.get_x()
250c.set_x(520)c.get_x()
5202. name mangling 机制的实现原理
我们看看 dict 属性里面有啥 c.__dict__
{_C__x: 250}虽然这里面没有看到 __x但是却多了一个 _C__x 的属性对不对
访问一下试试 c._C__x
520果然如此……这个就是传说中的名字改编术
做法其实也很简单就是下横线_加上类名再加上变量的名字。
方法名也是同样的道理 class D:
... def __func(self):
... print(Hello FishC.)
...d D()d.__func()
Traceback (most recent call last):File pyshell#12, line 1, in moduled.__func()
AttributeError: D object has no attribute __funcd._D__func()
Hello FishC.注意name mangling 机制是发生在类实例化对象时候的事情给对象动态添加属性则不会有同样的效果。
3. 不同数量的前缀下划线含义
不同数量的前缀下划线均有不同的特殊含义
4. 效率的提升之道
Python 对象存储属性的工作原理 —— 字典dict class C:
... def __init__(self, x):
... self.x x
... c C(250)c.x
250c.__dict__
{x: 250}对象动态添加属性就是将键值对添加到 dict 中 c.y 520c.__dict__
{x: 250, y: 520}甚至你可以直接通过给字典添加键值对的形式来创建对象的属性 c.__dict__[z] 666c.__dict__
{x: 250, y: 520, z: 666}c.z
666但是字典高效率的背后是以付出更多存储空间为代价的
如果我们明确知道一个类的对象设计出来就只是需要那么固定的某几个属性并且不需要有动态添加属性这样的功能那么利用字典来存放属性这种空间上的牺牲就是纯纯地浪费
针对这个情况Python 专门设计了一个 _ slots _ 类属性避免了利用字典存放属性造成空间上的浪费。 举个例子 class C:
... __slots__ [x, y]
... def __init__(self, x):
... self.x x
... c C(250)这样我们就创建了一个属性受限制的对象。
访问 slots 中列举的属性是没问题的 c.x
250c.y 520c.y
520如果想要动态地添加一个属性那就不好意思了 c.z 100
Traceback (most recent call last):File pyshell#27, line 1, in modulec.z 100
AttributeError: C object has no attribute z这种限制不仅体现在动态添加属性上如果在类的内部想创建一个 _slots _ 不包含的属性也是不被允许的 class D:
... __slots__ [x, y]
... def __init__(self, x, y, z):
... self.x x
... self.y y
... self.z zd D(3, 4, 5)
Traceback (most recent call last):File pyshell#8, line 1, in moduled D(3, 4, 5)File pyshell#6, line 6, in __init__self.z z
AttributeError: D object has no attribute z甚至是 dict 属性也不存在了 d.__dict__
Traceback (most recent call last):File pyshell#23, line 1, in moduled.__dict__
AttributeError: D object has no attribute __dict__因为使用了 slots 属性那么对象就会划分一个固定大小的空间来存放指定的属性这时候 dict 属性就不需要了空间也就节约了出来。 大家不要小看这点改变……
这里有位国外的老哥仅仅由于将一个类的三个属性都改为使用 slots 进行存储立竿见影地直接节省了 9G 的内存空间 一行代码竟然降低了 30% 的内存消耗确实惊人
不过这里有一点是需要特别强调的就是使用 slots 属性的副作用其实也相当明显那就是要以牺牲 Python 动态语言的灵活性作为前提。
使用了 slots 属性就没办法再拥有动态添加属性的功能了……
这可以说是它的一个副作用但实际上很多开发者却利用这个副作用来限制类属性的滥用。
最后还有一点需要大家知道的是继承自父类的 __ slots _ _ 属性是不会在子类中生效的Python 只关注各个具体的类中定义的 _ _ slots __ 属性 class E(C):
... pass
...e E(250)e.x
250e.y 520e.z 666e.__slots__
[x, y]对象e虽然拥有 slots 属性但它同时也拥有 dict 属性 e.__dict__
{z: 666}5.思维导图