在Python中,一切皆为对象,所有的对象都有一些相同的内容,在PyObject中定义。
//xk> 怎样实现继承
PyObject是Python中一切(new style)类的基类,其定义非常简单
//xk> Python3.2.2_Source/Include/Object.h typedef struct _object { _PyObejct_HEAD_EXTRA Py_ssize_t ob_refcnt; //xk> reference count struct _typeobject *ob_type; //xk> object的类型用type object来表示 } PyObject; |
怎么用C语言实现继承关系呢?子类继承了父类的内容,并有所增改,所以在内存布局上,只要把父类的内容放在对象的头部,就可以用父类指针指向子类对象。在Python内部,每个对象都有相同的对象头部——PyObejct的内容,这就使得在Python内部,对对象的引用变得非常统一,只需要用一个PyObject *指针就可以引用任意的对象。这对于实现多态是必要的。
//xk> 怎样表示类型
对象的类型定义了对象的数据成员和能够施加在对象之上的操作。查看Python3.2.2_Source/Include/Object.h中对_typeobejct的定义(内容非常多,不能在这里全部帖出来),包含了大量的函数指针。这些函数指针即表示该类型所定义的操作,亦即表示该类型的对象在运行时所表现的行为。
在这些操作信息中,有三个指针比较重要:tp_as_number, tp_as_sequence, tp_as_mapping。以tp_as_number为例,它是PyNumberMethonds *指针,而PyNumberMethonds结构体定义了作为一个数值对象应该支持的操作。类似的,tp_as_sequence表示作为一个序列对象所支持的操作;tp_as_mapping表示作为一个关联对象所支持的操作。可见:在Python中,一个对象可以同时是数值对象、序列对象、关联对象,关键看它支持哪些操作,也就是定义了哪些非NULL的函数指针。因此,Python对象的多态性是基于行为的,而不像C++/Java等语言中多态性是基于类型的。Python对象实际上是全类型的,可以有的函数指针全部都有,只不过很多函数指针都是NULL,只要你实现了该函数,python对象就能表现出该行为。
>>> class MyInt(int): def __getitem__(self, key): return key + str(self) >>> a = MyInt(1) >>> b = MyInt(2) >>> print a + b 3 >>> a['key'] 'key1' |
//xk> Python对象的多态性
通过PyObject和PyTypeObejct,Python利用C语言实现了类似C++所提供的对象多态性(但是有所不同)。在Python中创建一个对象比如PyIntObject对象时,Python内部是用PyObject *指针而不是PyIntObject *指针来保存和维护这个对象,在Python内部各个函数之间传递的都是一种泛型指针——PyObject *,因此无法根据指针类型判断所指的对象究竟是个什么类型,只能从指针所指对象的ob_type域动态地进行判断。由此,Python实现了多态机制。
//xk> 乱弹:C哲学和C++哲学的比较
C哲学:保持简单。
C++哲学:用复杂的工具对付复杂的现实问题,以此获取解决方案的简单直接。
C和C++都意识到程序设计的本质问题是控制复杂度,只不过它们采用了不同的思路。
C语言选择用分治法,模块化将一个复杂问题分解成许多相对简单的小问题,并精心设计模块之间的通信。这里的模块可以是一个函数、一个进程甚至一个独立的程序。Unix工具链哲学与此一脉相承。
《C++沉思录》中阐明:类似汽车制造等传统工业,一方面用户接口越来越简单,另一方面内部实现越来越复杂。我们生活在一个如此复杂的世界里,因此Java和C#也不可避免地变得越来越复杂。C++的复杂源于要解决的现实问题的复杂。
从理论上争论孰优孰劣是毫无意义的,两者都很有道理。C语言的选择有一定的问题,从整体来看模块化的设计容易导致多余(Python的每个对象都要定义对所有类型的操作的支持,大量的函数指针被设置为NULL),用C来实现面向对象的机制明显不如C++简单直接。虽然如此,C语言貌似要比C++受到更广泛的支持。C++貌似真的过于复杂了,既难于学习,开发效率又低。在面对非常非常复杂的问题时,从整体上来把握对操刀者提出了很高的要求,分而治之虽然难免冗余,好歹能够可行。
最后说一句,对学生来说,选择哪个都没有错,饿死于干草堆之间才是最大的愚蠢。学习尽量与手头上的项目结合,把手上看似平淡无奇的事情做得比别人深入一步,learn by doing it.