尽管python在function programming中有着其他语言难以企及的的优势,但是我们也不要忘了python也是一门oo语言哦。因此我们关注python在fp上的优势的同时,还得了解一下python在oo方面的特性。
要讨论python的oo特性,了解python中的class自然是首当其冲了。在python中定义class和创建对象实例都很简单,具体代码如下:
class grandpa:
def __init__(self):
print(‘i\’m grandpa’)
class father(grandpa):
def __init__(self):
print(‘i\’m father!’)
class son(father):
“””a simple example class”””
i = 12345
def __init__(self):
print(‘这是构造函数,son’)
def sayhello(self):
return ‘hello world’
if __name__ == ‘__main__’:
son = son()
# 类型帮助信息
print(‘类型帮助信息: ‘,son.__doc__)
#类型名称
print(‘类型名称:’,son.__name__)
#类型所继承的基类
print(‘类型所继承的基类:’,son.__bases__)
#类型字典
print(‘类型字典:’,son.__dict__)
#类型所在模块
print(‘类型所在模块:’,son.__module__)
#实例类型
print(‘实例类型:’,son().__class__)
运行情况:
python 3.3.2 (v3.3.2:d047928ae3f6, may 16 2013, 00:03:43) [msc v.1600 32 bit (intel)] on win32
type “copyright”, “credits” or “license()” for more information.
>>> ================================ restart ================================
>>>
这是构造函数,son
类型帮助信息: a simple example class
类型名称: son
类型所继承的基类: (,)
类型字典: {‘__module__’: ‘__main__’, ‘sayhello’: , ‘__doc__’: ‘a simple example class’, ‘__init__’: , ‘i’: 12345}
类型所在模块: __main__
这是构造函数,son
实例类型:
>>>
#python支持多重继承
首先第一点,你会发现class的定义中有一个括号,这是体现继承的地方。 java用extends,c#、c++用冒号(:),python则用括号了。从括号中包含着两个值,聪明的你一定可以发现:python支持多重继承;
#__init__是class中的构造函数
第二点,__init__是class中的构造函数,两种不同形式的构造函数体现了python支持函数重载。在构造函数中,有一个特别的参数self,其含义与我们在java和c#中常见的this是一样的。在这里需要强调一点:在class中定义的方法实质上也是function,但是在方法定义的时候必须包含self这个参数,而且必须将self这个参数放在第一位;
#python成员变量
第三点,在python中,你并不需要显式的声明class的data members,而是在赋值的时候,被赋值的变量就相应成为了class的data memebers,正如代码中的x和y。不仅你不需要显式的声明data members,更加特别的,你甚至可以通过del方法将class中的data memebers给删掉。当我第一次看到这样的特性的时候,着实吃了一惊。毕竟oo的第一条就是封装了,但是这样的特性是不是破坏了封装的特性呢?
#python方法二义性问题
第四点,由于python支持多重继承,因此就有可能出现方法二义性问题[1]。然而由于python遵循深度优先的搜寻法则,很好地避免了方法二义性的问题。例如在以上的代码中,myclass同时继承于baseclassa和baseclassb,假设myclass调用一个叫derivedmethod方法,derivedmethod同时定义在baseclassa和baseclassb中,且signature也完全相同,那么baseclassa中的方法将被调用。如果baseclassa中并没有定义derivedmethod,而是baseclassa的父类定义了这个方法的话,将会是baseclassa的父类中derivedmethod被调用。总之,继承方法搜索的路径是先从左到右,在选定了一个baseclass之后,将会一直沿着该baseclass的继承结构进行搜索,直至最顶端,然后再到另外一个一个baseclass。
就先说着这么多了,对于python中oo的特性将会在以后的post中有进一步的讲述。
[1] 方法二义性:由于一个类同时继承于两个或者多个父类,而在这些父类当中存在着signature完全相同的方法,那么编译器将无法判断子类将继承哪个父类中的方法,从而导致方法二义性问题