一 对象生命周期

对象的生命周期由对象的创建,操作和销毁几个部分组成.

对象的生命周期第一阶段是它所属的类的定义.

下一个阶段是调用__init__时实例的实例化.内存被分配来存储实例.

在调用__init__方法之前,python首先调用__new__方法.

这之后,对象就可以使用了

最终对象会完成使用,并可以被销毁.

当一个对象被销毁时,分配给它的内存被释放,并可用于其他目的.

当引用计数达到零时,就会发生对象的破坏.引用计数是引用一个对象的变量和其他元素的数量.

如果什么都没有引用(引用计数为零),什么都不能与它交互,所以它可以安全地删除.

在某些情况下,两个(或更多)对象只能被彼此引用,因此也可以被删除.

del语句会将对象的引用计数减少一个,这通常会导致删除.

del语句的魔术方法是__del__

不再需要的对象删除的过程称为垃圾收集

总之,当一个对象的引用计数被分配一个新的名字或者放在一个容器(列表,元组或字典)中时,它的引用计数会增加.

当用del语句删除对象的引用计数时,它的引用计数会减少,引用被重新分配或引用超出作用域.当一个对象的引用计数达到零时,python会自动删除它.

例如:

a=42 #Create object<42>
b=a # 增加对象<42>的一个引用计数
c=[a] # 增加对象<42>的一个引用计数
del a #减少对象<42>的一个引用计数
b=100 #减少...一个引用计数
c[0]=-1 #减少..一个引用计数

c语言这样的'低级语言'没有这种自动内存管理

二 数据隐藏

面向对象编程的一个关键部分是封装,它涉及将相关的变量和函数打包到一个简单易用的对象中--一个类的实例.

一个相关的概念就是数据隐藏.它指出一个类的实现细节应该被隐藏,并且为那些想要使用这个类的用户提供一个干净的标准接口

在其他编程语言中,这通常使用私有方法和属性来完成,这些私有方法和属性阻止对类中某些方法和属性的外部访问.

python略有不同.你不应该对任何一个阶段的部分进行任意的限制.因此,没有办法强制一个方法或属性是严格私密的.

但是,有些方法可以阻止人们访问某个类的某些部分,例如通过表示它是一个实现的细节,并且应该自己承担风险.

python的私有方法就是:不鼓励外部代码调用的方法.

弱的私有方法和属性在开头只有一个下划线.

这表示它们是私有的,不应该被外部代码调用.但是,它大多只是一个约定,并不会阻止外部代码访问它们.

它唯一的实际效果是从moudule_name 导入* 时, 不会导入以单个下划线开头的变量.

例如:

class Queue: def __init__(self,contents): self._hiddenlist=list(contents) def push(self,value): self._hiddenlist.insert(0,value) def pop(self): return self._hiddenlist.pop(-1) def __repr__(self): return'Queue({})'.format(self._hiddenlist)queue=Queue([1,2,3])print(queue)queue.push(0)print(queue)queue.pop()print(queue)print(queue._hiddenlist)

结果:

python变量生命周期 python 生命周期_python

强烈的私有方法和属性在名称的开始处有一个'双下划线'.这导致他们的名字错位,这意味着它们不能从类外访问.

这样做的目的不是确保它们保持私有,而是为了避免错误,如果存在具有相同名称的方法或属性的子类时.

名称 错位 方法 仍然可以在外部访问,但是以不同的名称访问.Spam类的__private方法可以通过_Spam__private方法外部访问.

例如:

class Spam: __egg=7 def print_egg(self): print(self.__egg)s=Spam()s.print_egg()print(s._Spam__egg)print(s.__egg)

结果:

python变量生命周期 python 生命周期_引用计数_02

42>42>42>42>