概述
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
我们以一个例子来说明面向过程和面向对象在程序流程上的不同之处。
假设我们要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个dict表示:
std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }
# 而处理学生成绩可以通过函数实现,比如打印学生的成绩:
def print_score(std):
print('%s: %s' % (std['name'], std['score']))
print_score(std1)
print_score(std2)
如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性(Property)。如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来。给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法(Method)。面向对象的程序写出来就像这样:
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print('%s: %s' % (self.name, self.score))
michael = Student('Michael', 98)
bob = Student('Bob', 81)
michael.print_score()
bob.print_score()
类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
以上面的代码为例:class Student(object):
定义了Student类;bob = Student('Bob', 81)
其中bob是实例,也是通过Student类创造出来的具体对象(name:‘Bob’,score:81);.print_score()
表示对象的方法,在定义Student类时就已经确定了。所以,虽然实例michael和bob的数据不同,但是它们都拥有相同的方法.print_score()
。
__call__()
函数
__call__()
函数可以使一个类实例像函数一样被调用。
下面以斐波那契数列为例来说明__call__()
函数的用途。斐波那契数列(Fibonacci sequence)在数学上以如下递归的方法定义:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)。也就是后一个数为前两个数相加,具体数值为:0、1、1、2、3、5、8、13、21、34、……
使用面向对象编程的代码如下:
class Fib(object):
def __init__(self):
pass
def __call__(self,num):
a,b = 0,1;
self.l=[]
for i in range (num):
self.l.append(a)
a,b= b,a+b
return self.l
# 输出前10个斐波那契数列
f = Fib()
print(f(10))
在定义Fib类中使用了__call__()
函数,使得实例 f 可以像函数一样被调用,f(10)中的10 对应就是__call__()
函数中的参数 num 。
参考文献:
廖雪峰Python教程