Python: Numeric and Dynamic Typing

      看书还是能学到新东西的,好好的了解了一下Python的Dynamic Typing以及垃圾收集。收获蛮大。

Numeric Type:

      这是最常用也是最简单的数据类型。值得注意的是 // 和 / 在python2 和 python3 中的区别。在python3中,/ 始终是浮点除。

      python的各种进制数也很好用。关键输出要注意,比如输出16进制,前面会自动加上0x,这在有些情况下是不希望出现的。使用format就可以解决这个问题。数的操作都比较浅显易懂,Fraction等都已经涉及过。估计也难得用python来位操作。

Dynamic Typing:

      Python的优点之一是不需要声明变量类型。这是怎么做到的?Python的每个变量都可以认为是一个指针,更确切是”Reference”。然后变量引用对象。对象知道自己是什么对象。因为每个对象都有 type designator和reference counter,所以”Types Live with Objects, Not Variables”。类型根本不关变量的事。
      这样做就需要垃圾管理机制。就是python的gc。每当引用变为0,就可以回收该对象的内存空间。但是这里有一个很著名也很普通的问题: cyclic references。比如 L = [1,2],L.append(L) ,就构成了一个循环引用。Python是怎么处理的我就不管了。
      当Python要比较的时候,可以用 ==,代表的是值相等,也可以用is,代表的是引用是否相同。比如:

      因为这种机制,很多对象都是共享的(Shared References )。不可变类型不要紧,可变类型就有问题,一旦改变某个变量的引用,就会使其他变量也变化,就是所谓的in-place object changes。要灵活运用L[:]和copy.deepcopy()

refcount 和 weakref:

      不深入看看Python的引用是无法完全理解这种机制的。还好Python提供了查看引用的方法。这里要注意对于一个数的引用是出乎意料的,这是因为Python的Cache机制。反正数是不可变的,多给引用完全没有问题。同样小字符串也是有cache的。然后这里sys.getrefcount,总是多1,查看文档,发现这是因为这个函数本身就临时引用了一次变量,想想蛮有道理。

      为了避免cyclic references,python提供了 weak ref机制,主要原理是这次引用不增加对该对象引用的计数,就相当于没引用。好吧,我讲不清。看这里。然后代码也能说明一切。这个功能的主要作用是防止一些大对象不能及时回收。list,dict什么的不能直接支持,要包裹一下。