面向过程编程:首先分析出解决问题所需要的步骤(即“第一步做什么,第二步做什么,第三步做什么”),然后用函数实现各个步骤,再依次调用。
import math
# 变量key代表循环运行程序的开关
key = 1
# 采集信息的函数
def myinput():
choice = input('请选择计算类型:(1-工时计算,2-人力计算)')
if choice == '1':
size = float(input('请输入项目大小:(1代表标准大小,请输入小数)'))
number = int(input('请输入人力数量:(请输入整数)'))
time = None
return size,number,time
# 这里返回的数据是一个元组
if choice == '2':
size = float(input('请输入项目大小:(1代表标准大小,请输入小数)'))
number = None
time = float(input('请输入工时数量:(请输入小数)'))
return size,number,time
# 这里返回的是一个元组
# 完成计算的函数
def estimated(my_input):
# 把元组中的数据取出来
size = my_input[0]
number = my_input[1]
time = my_input[2]
# 人力计算
if (number == None) and (time != None):
number = math.ceil(size * 80 / time)
print('项目大小为%.1f个标准项目,如果需要在%.1f个工时完成,则需要人力数量为:%d人' %(size,time,number))
# 工时计算
elif (number != None) and (time == None):
time = size * 80 / number
print('项目大小为%.1f个标准项目,使用%d个人力完成,则需要工时数量为:%.1f个' %(size,number,time))
# 询问是否继续的函数
def again():
# 声明全局变量key,以便修改该变量
global key
a = input('是否继续计算?继续请输入y,输入其他键将结束程序。')
if a != 'y':
# 如果用户不输入'y',则把key赋值为0
key = 0
# 主函数
def main():
print('欢迎使用工作量计算小程序!')
while key == 1:
my_input = myinput()
estimated(my_input)
again()
print('感谢使用工作量计算小程序!')
main()
我们根据“采集信息——计算数据——继续采集信息”这个过程封装了三个函数,再依次调用,按规定顺序执行程序。
而面向对象编程,会将程序看作是一组对象的集合(还记得对象包括类对象和实例对象吧)。
用这种思维设计代码时,考虑的不是程序具体的执行过程(即先做什么后做什么),而是考虑先创建某个类,在类中设定好属性和方法,即是什么,和能做什么。
接着,再以类为模版创建一个实例对象,用这个实例去调用类中定义好的属性和方法即可。
如果把上述面向过程编程的代码改成面向对象编程,我们可以先创建一个Project类,在类中定义好属性和方法,再创建一个实例。
代码就是这样的,大致感受一下即可:
import math
class Project:
def __init__(self):
self.key = 1
def input(self):
choice = input('请选择计算类型:(1-工时计算,2-人力计算)')
if choice == '1':
self.size = float(input('请输入项目大小:(1代表标准大小,请输入小数)'))
self.number = int(input('请输入人力数量:(请输入整数)'))
self.time = None
if choice == '2':
self.size = float(input('请输入项目大小:(1代表标准大小,请输入小数)'))
self.number = None
self.time = float(input('请输入工时数量:(请输入小数)'))
def estimated(self):
# 人力计算
if (self.number == None) and (self.time != None):
self.number = math.ceil(self.size * 80 / self.time)
print('项目大小为%.1f个标准项目,如果需要在%.1f个工时完成,则需要人力数量为:%d人' %(self.size,self.time,self.number))
# 工时计算
elif (self.number != None) and (self.time == None):
self.time = self.size * 80 / self.number
print('项目大小为%.1f个标准项目,使用%d个人力完成,则需要工时数量为:%.1f个' %(self.size,self.number,self.time))
def again(self):
a = input('是否继续计算?继续请输入y,输入其他键将结束程序。')
if a != 'y':
# 如果用户不输入'y',则把key赋值为0
self.key = 0
# 主函数
def main(self):
print('欢迎使用工作量计算小程序!')
while self.key == 1:
self.input()
self.estimated()
self.again()
print('感谢使用工作量计算小程序!')
# 创建实例
project1 = Project()
project1.main()
可以发现,在此例中,用类编写一个直观的好处就是参数的传递会比普通函数要省事很多,也不必考虑全局变量和局部变量,因为类中的方法可以直接调用属性。
可想而知,当项目难度越大,需要的参数越多,用类编写在程序的可拓展性、可读性、维护成本都会更胜一筹。
这就是面向对象编程:以对象为中心,将计算机程序看作一组对象的集合。
对比图如下:
总结一下:和之前说过的函数类似,面向对象编程实际上也是一种对代码的封装。只不过,类能封装更多的东西,既能包含操作数据的方法,又能包含数据本身。所以,代码的可复用性也更高。
而且,对于需要长期更新的代码而言,面向对象编程写成的代码结构会更清晰。所以,代码的可读性、可拓展性和可维护性这几个方面都会优于面向过程编程。
还有一点不得不提的是:面向对象编程,将代码具体的数据和处理方法都封装在类中,让我们不用完全了解过程也可以调用类中的各种方法。
这个优势让我们可以在 Python 中轻松地调用各种标准库、第三方库和自定义模块(可以简单理解成别人写好的类),这是Python 之所以这么强大和热门的主要原因之一。
这也是为什么我在开头说“面向对象编程,会为你打开一个新的世界”。将他人封装好的代码为自己所用,效率和能做的事情自然是天壤之别。
不过万丈高楼平地起,这些我们以后能够做到的事,都是建立在今天的基础学习和练习之上。
好,现在请你将目光从屏幕上稍稍移开一会儿,在大脑里回顾一下自己对类、实例、对象、属性和方法这些词的理解。
已经都过了一遍了吗?确定的话,再往下走。
你是否想到现实中的类(如鸟类)和编程中的类(如 int)的对比?是否想到了某群体下的某个体,类似于某个类创建的某个实例?
是否想到了现实事物也存在着属性(具有一定特征)和方法(能完成某些行为)?是否……
所以,可以说:编程世界的创建,是基于人对现实世界的理解。只要你用心留意,就能发现这两个世界之间各种关联,包括之前学过的知识。
编程能将对世界的理解投射到代码里,反过来,编程也能通过代码来影响世界。从这个角度来看,改变世界这件事离我们其实都并不远。
希望编程可以加深你对世界的理解,并增强你改变世界的能力。
关于类,今天只提到了基础概念和基础用法。除了类的创建和调用外,还有一些类的操作,是类成为面向对象编程中的主要工具的真正原因。
那么类的高阶操作主要有哪些呢?下一站我们继续探讨!