Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12778
  • 博文数量: 5
  • 博客积分: 185
  • 博客等级: 入伍新兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-10 11:45
文章分类
文章存档

2011年(5)

我的朋友
最近访客

分类: Python/Ruby

2011-07-24 19:42:08

 

    在学习更复杂的对象类型之前,先掌握python的动态类型这一概念,是十分必要的。动态类型以及它提供的多态性是python语言简洁性和灵活性的基础。
----------------------------------------------------------------------------------------------
变量与类型
变量是系统表的元素,并拥有指向对象连接的空间(Variables are entries in system table,
with spaces for links to objects)。变量绝不会有任何的类型或与类型相关的信息。变量是通用的,它只是在某个时间,某个位置简单的引用了一个对象而已。类型属于对象。

变量、声明与初始化
因为它没有类型,所以变量不需要声明;因为它会在程序运行过程中自动创建,并由此获得多态性,所以不应该被声明。但是需要被初始化,并且要在使用前赋值。例如,变量初始化,会将对象的引用计数器初始化为0.

对象与类型
Ⅰ对象在python的作用,与数据结构在C/C++中的作用一样。而变量名在python中的作用,与指针在C/C++中类似。
Ⅱ对象被分配到足够的内存空间以表示它的值,它与这块内存空间紧密相关。
Ⅲ 对象有复杂的结构。python的对象体系用C实现,对象结构对应C中的结构体。
typedef struct _typeobject
{   
    PyObject_VAR_HEAD                          /*与C实现有关的宏*/
    char *tp_name;                             /*in format     "." */   
    int tp_basicsize, tp_itemsize;             /* For allocation */   

   /* Methods to implement standard operations */   
    destructor tp_dealloc; 
    printfunc tp_print;   
     ……    
   /* More standard operations (here for  binary compatibility) */    

   hashfunc tp_hash;    
   ternaryfunc tp_call;     ……    
} PyTypeObject;   
可以说,对象就是一块有着一定结构和一些方法的内存空间。
Ⅳ 对象有两个标准的头部信息。一个是类型标识符,一个是引用计数器。引用计数器与python的垃圾回收有关。

变量与对象
从变量到对象的连接称为引用,它在底层通过指针实现。使用变量,即是通过变量名引用对象。
从对象到引用的过程:
>>> a = 3
1.创建一个对象,它的值是3
2.如果a未被创建,则创建一个名为a的变量
3.将a与对象3像连接


---------------------------------------------------------------------------------------------
对象的垃圾收集与缓存复用机制

每当变量名被赋予一个新的对象,它先前能引用的对象就会被销毁(如果那个对象没有被其他变量引用)。
这就是垃圾回收机制。它的实现过程与对象的引用计数器有关:当变量初始化时,计数器同时初始化为0,
随着对象会被变量引用,计数器值会增加;当引用结束,计数器值减少;当计数器又回到0时,对象同时
被回收。
作为垃圾回收机制的补充,python有一个循环检测器在及时地检测并回收带有循环引用的对象。这个功能
是可选的。
注意,有的时候垃圾回收机制会影响程序的性能。所以,可以在某处事先手动关闭垃圾回收功能,在那个
更需要性能的程序模块之后开启回收。

并不是所有的对象在引用它的变量指向别处后离开被销毁,如小的整数和小的字符串,它们依然会短时间存在于系统表中,并可以被引用。
情况一:
>>> l = [1, 2, 3]
>>> m = [1, 2, 3]
>>> l == m
True
>>> l is m                        #m = [1, 2, 3]创建了新对象
False
情况二:
>>> x = 2
>>> y = 2
>>> x == y
True
>>> x is y                        #y=2,并没有创建一个新对象
True
----------------------------------------------------------------------------------------------
共享引用
在某一时刻,一个变量只能引用一个对象,但是一个对象可以被多个变量引用,这就是共享引用:
>>> a = 3
>>> b = a
>>> b
3


在运行b=a时,b并没有再次创建一个值为3的对象,而只是与先前那个对象建立了连接。并且,这种连接
与a没有多大关联,若a再被赋予新值,它将指向一个新建的对象,所以:
>>> a = 'spam'
>>> b
3


但是情况并非总是这样。当a与b共享引用时,在a所引用的对象发生变化,可能只是在原有对象的基础上进行的修改,于是,b所引用的对象的值也发生了修改:
>>> a = [1, 2, 3]
>>> b = a
>>> a[0] = 5
>>> a
[5, 2, 3]
>>> b
[5, 2, 3]


这种情况也许不是你想要的。为了不让这样的事情发生,在不同的情况下有不同的方法解决这个问题。如:
>>> a = [1, 2, 3]
>>> b = a[:]
>>> a[0] = 4
>>> a
[4, 2, 3]
>>> b
[1, 2, 3]


上面使用的方法是分片拷贝技术,更通用的做法是:
>>> import copy
>>> a = [1, 2, 3]
>>> b = copy.copy(a)            #b = copy.deepcopy(a)
>>> a[0] = 4
>>> a
[4, 2, 3]
>>> b
[1, 2, 3]
----------------------------------------------------------------------------------------------
如果两个变量引用的对象的值相等,有的时候它们的确引用了同一个对象,有的时候却是引用了两个值一样
对象,情况一(共享引用):
>>> l = [1, 2, 3]
>>> m = l
>>> l == m
True
>>> l is m
True
情况二:
>>> l = [1, 2, 3]
>>> m = [1, 2, 3]
>>> l == m
True
>>> l is m
False

还可以用下面方法:
>>> import sys
>>> x = 32
>>> sys.getrefcount(32)        #测试32被引用的次数
16
>>> y = 32
>>> sys.getrefcount(32)        #再次测试发现32引用次数增加1,这个32不是新建对象
17






































































阅读(2038) | 评论(0) | 转发(0) |
0

上一篇:数字类型

下一篇:类型总结-列表-字典

给主人留下些什么吧!~~