大多数编译型语言,变量在使用前必须先声明,其中C语言更加苛刻:变量声明必须位于代码块最开始,且在任何其余语句以前。其余语言,想C++和java,容许“随时随地”声明变量,好比,变量声明能够在代码块的中间,不过仍然必须在变量被使用前声明变量的名字和类型。在Python中,无序此类显式变量声明语句,变量在第一次被赋值时自动声明。和其余大多数语言同样,变量只有被建立和赋值后才能被使用。html
1 # 变量未声明 2 >>> x 3 Traceback (most recent call last): 4 File "<stdin>", line 1, in <module> 5 NameError: name 'x' is not defined 6 7 #变量一旦被赋值,就能够经过变量名来访问它 8 9 >>> x=1 10 >>> y="It's wonderful." 11 >>> x 12 1 13 >>> y 14 "It's wonderful."
Python中不但变量名无需事先声明,并且也无需类型声明。在Python语言中,对象的类型和内存占用都是运行时肯定的。尽管代码被编译成字节码,Python仍然是一种解释型语言。在赋值时解释器会根据语法和右侧的操做数来决定新对象的类型。在对象建立后,一个该对象的应用会被赋值给左侧的变量。java
做为一个负责任的程序员,咱们知道在为变量分配内存时,是在借用系统资源,在用完以后,应该释放借用的系统资源。Python解释器承担了内存管理的复杂任务,这大大简化了应用程序的编写。程序员
要保持追踪内存中的对象,Python使用了引用计数这一简单技术。也就是说Python内部记录着全部使用中的对象 各有多少引用。一个内部跟踪变量,称为引用计数器。每一个对象各有多少个引用,简称引用计数。当对象被建立时,就建立了一个引用计数,当这个对象再也不须要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。(并非100%这样)函数
当对象被建立并赋值给变量时,该对象的引用计数就被设置为1。spa
当同一个变量又被赋值给其余变量时,或做为参数传递给函数、方法或类实例,或者被赋值为一个窗口对象的成员时,该对象的一个新的引用,或者称为别名,就被建立(则该对象的引用计数就自动加1)。code
以下代码: htm
1 >>> x = 3 2 >>> y = x
语句x=3咱们将3赋值给x。x是第一个引用,所以,该对象的引用计数被设置为1。语句y=x建立了一个指向同一对象的别名y。事实上并无为y建立一个新的对象,而是该对象的引用计数增长了一次(变成了2)。这是对象引用计数增长的方式之一。还有一些其余的方式也能增长对象的引用计数,好比该对象做为参数被函数调用或这个对象被加入到某个列表等对象当中。对象
总之,对象的引用计数增长是:blog
x = 3内存
y = x
foo(x)
mylist = [1,2,x,'xyz']
当对象的引用被销毁时,引用计数会减少。最明显的例子就是当引用离开其做用范围时,这种状况最常常出如今函数运行结束时,全部的局部变量都被自动销毁,对象的引用计数也就随之减小。
当变量被赋值给另一个对象时,原对象的引用计数也会自动减1:
1 >>> foo = 'xyz' 2 >>> bar = foo 3 >>> foo = 123
当字符串对象“xyz”被建立并赋值给foo时,它的引用计数是1。当增长一个别名bar时,引用计数变成了2。不过当foo被从新赋值给整型对象123时,xyz对象的引用计数自动减1,又从新变成了1。
其余形成对象引用计数减小的方式包括使用del语句删除一个变量,或者当一个对象被移出一个窗口对象时。
对象引用计数减小的状况:
del y
x = 123
mylist.remove(x)
del mylist
再也不使用的内存会被一种称为垃圾收集的机制释放。像上面说的,虽然解释器跟踪对象的引用计数,但垃圾收集器负责释放内存。垃圾收集器是一块独立代码,它用来寻找计数为0的对象。它也负责检查那些虽然引用计数大于0但也应该被销毁的对象。特定情形会致使循环引用。