第1章 场景描述
白小灵,人如其名,身型娇小,有点古灵精怪,大学动漫专业毕业,是典型的二次元美女。在大四那一年,她遇上了阳光帅气、家境殷实的白马王子小帅,她认定小帅就是自己的菜,随后开始了一段浪漫的校园恋情。走出大学校园的那一年,小灵和小帅步入了婚姻的殿堂,接下来就是怀孕生子,相夫教子,小灵成为了名副其实的全职太太。然而命运没有总是眷顾她,他们的婚姻最终没能跨越七年之痒,小灵重回单身时代。当看到自己大学同学都在动漫产业中打拼多年,找到了自己的位置,有的还小有成就,心生羡慕和嫉妒。争强好胜的小灵不甘沦落为同学眼中的笑柄,痛定思痛,决定归零出发,另选赛道,投身于自己喜爱的IT行业。凭借大学动漫专业深厚的美术功底,小灵成功入职了当地一家IT头部企业,从事前端页面的美工设计。小灵以此为起点,系统地学习了Python、MySQL和前端开发技术,期待着有机会从事软件设计和项目开发工作,她执念地认为软件设计就是科技与艺术的完美结合。机遇总是青睐有准备的人,在从事3年网页美工设计之后,她有幸独立承担了寰银学堂网站建设项目的开发任务,具体工作包括前端页面设计和编码、后台Python程序编写、MySQL数据库设计,以及云服务器部署实施。项目投产后,深受客户好评,这个网站一直运行至今。寰银学堂网站项目也成为白小灵的代表作之一,对她而言具有里程碑的意义,在本文的参考资料部分有白小灵代表作的链接,有兴趣的读者可前往围观。
现在白小灵已成为公司软件开发部技术总监,统领着拥有40+多人的软件开发团队。为了全面提升技术团队整体开发和运维能力,增强团队协作精神,为此实施了软件项目设计规范的蓝图项目,其重要内容之一就是统一软件开发团队的编程风格。在蓝图项目中关于Python代码编写风格描述为三种类型:菜鸟版(脚本法)、码农版(函数法)和大牛版(模块法)。其核心理念可以归纳为15个字:拒绝菜鸟版、掌握码农版、推崇大牛版。下面我们就来一探究竟,了解三大经典的编程模板,或许是对Pythoner具有很好的学习与借鉴作用。
第2章 编程思路
下面我们借助于一个编程案例,介绍和解释菜鸟版、码农版和大牛版等三种编程风格或模板,然后对三种不同的编码风格进行分析和点评。
现将具体的编程案例需求描述如下:
使用Python编写几何图形面积计算器程序。要求从键盘输入相关数据,计算:圆、三角型、矩形、扇形,正方形等5种图形的面积。
第3章 代码实现
3.1 菜鸟版
下面是菜鸟版的几何图形计算器,取名get_areas1.py,源码如下所示:
"""
脚本法 get_areas1.py : 几何图形面积计算器
"""
# 计算圆面积
radius = float(input('输入圆的半径:'))
area = 3.14 * radius ** 2
print('圆面积:', area)
# 计算三角形面积
bottom = float(input('输入三角形的底:'))
height = float(input('输入三角形的高:'))
area = bottom * height / 2
print('三角形面积:', area)
# 计算矩形面积
width = float(input('输入矩形宽度:'))
height = float(input('输入矩形高度:'))
print('矩形面积:', width * height)
# 计算扇形面积
radians = float(input('输入扇形弧度:'))
radius = float(input('输入扇形半径:'))
area = radians / 360 * 3.14 * radius ** 2
print('扇形面积:', area)
# 正方形面积
width = float(input('输入正方形边长:'))
print('正方形面积:', width*width)
3.2 码农版
下面是码农版的几何图形面积计算器的源码,取名get_areas2.py
"""
函数法 get_areas2.py : 几何图形面积计算器
"""
from math import pi # ①
def circle_area(radius): # ②
"""
功能:计算圆面积
参数:radius - 圆半径
"""
area = pi * radius ** 2
return round(area, 2)
def triangle_area(bottom, height):
"""
功能:计算三角形面积
参数:bottom - 底
height - 高
"""
area = bottom * height / 2
return round(area, 2)
def rect_area(width, height):
"""
功能:计算矩形面积
参数:width - 矩形的宽度
height - 矩形的高度
"""
area = width * height
return round(area, 2)
def square_area(width):
"""
功能:计算正方形面积
参数:width - 正方形边长
"""
area = rect_area(width, width)
return round(area, 2)
def sector_area(radians, radius):
"""
功能:计算扇形面积
参数:radians - 弧度
radius - 半径
"""
area = radians / 360 * circle_area(radius)
return round(area, 2)
def get_data(prompt): # ③
"""
功能:输入一个数字
"""
while True:
data = input(prompt)
try:
data = float(data)
break
except ValueError:
print('数据错误,重试!')
continue
return data
def main(): # ④
# 计算圆面积
radius = get_data('输入圆的半径:')
print('三角形面积:', circle_area(radius))
# 计算三角形面积
bottom = get_data('输入三角形的底:')
height = get_data('输入三角形的高:')
print('三角形面积:', triangle_area(bottom, height))
# 计算矩形面积
width = get_data('输入矩形宽度:')
height = get_data('输入矩形高度:')
print('矩形面积:', rect_area(width, height))
# 计算扇形面积
radians = get_data('输入扇形弧度:')
radius = get_data('输入扇形半径:')
print('扇形面积:', sector_area(radians, radius))
# 正方形面积
width = get_data('输入正方形边长:')
print('正方形面积:', square_area(width))
if __name__ == '__main__': # ⑤
main()
重要语句说明如下:
语句①使用模块math中定义的pi,要比直接使用常数3.14更好,pi的精度要高得多;
语句②相对于脚本版程序,计算圆面积使用了函数封装,成为独立的调用执行单元,可重用代码;
语句③定义一个具有容错功能的数字输入函数;
语句④定义程序的主入口,通过函数调用的方式计算各种几何图形的面积;
语句⑤是Python程序的标配,可以精准区分Python程序的执行方式;你可通过如下两种方式执行代码,应用场景有所区别:
方式一:
python get_area2.py
这是我们常见的使用方式,此时__name__的值是:__main__,Python解释器将自动执行函数main()。
方式二:
import get_area2 as area
area.circle_area(10)
通过由其他模块导入的方式,__name__的值是:get_area2,取自模块名称。Python计算器此时不再执行main()中的语句。
3.3 大牛版
程序由两个部分组成,一个是基础模块get_area.py,它是存放在Python包areas中的模块;另一个是main.py模块,这是主程序。其中演示了各种图形面积函数的使用方法,特别是多种不同的参数传递方式。
get_area.py 模块代码如下所示:
"""
模块法 get_areas.py : 几何图形面积计算器核心函数
"""
# 定义模块公共接口
__all__ = ['rect_area', 'circle_area', 'triangle_area', 'square_area', 'sector_area'] # ①
from math import pi
def data_checked(func): # ②
"""
功能:数据检测的装饰器
参数:func - 被装饰函数
"""
def wrapper(*args):
try:
arg_lst = [float(arg) for arg in args] # ③
if [arg for arg in arg_lst if arg < 0]:
raise ValueError # ④
except ValueError: # ⑤
print('数据有无,请重试!')
return None
return func(*arg_lst)
return wrapper
@data_checked # ⑥
def circle_area(radius):
"""
功能:计算圆面积
参数:radius - 圆半径
"""
area = pi * radius ** 2
return round(area, 2)
@data_checked
def triangle_area(bottom, height):
"""
功能:计算三角形面积
参数:bottom - 底
height - 高
"""
area = bottom * height / 2
return round(area, 2)
@data_checked
def rect_area(width, height):
"""
功能:计算矩形面积
参数:width - 矩形的宽度
height - 矩形的高度
"""
area = width * height
return round(area, 2)
@data_checked
def square_area(width):
"""
功能:计算正方形面积
参数:width - 正方形边长
"""
area = rect_area(width, width)
return round(area, 2)
@data_checked
def sector_area(radians, radius):
"""
功能:计算扇形面积
参数:radians - 弧度
radius - 半径
"""
area = radians / 360 * circle_area(radius) # ⑦
return round(area, 2)
重要的语句说明如下:
语句①定义对外开放的API函数接口,只有在列表__all__中定义的对象,方可被其它模块访问;
语句②定义的装饰器函数data_checked(func),它是在调用函数func之前,由Python自动调用。它用于对被装饰函数func的参数进行合法性检查,这里只有数字或者数字字符串才是有效性参数,方能正确执行函数func的功能;
语句③通过列表推导式将参数类型转换为浮点数;
语句④针对参数为负数的情况,生成一个异常ValueError,以便由语句⑤接管处理;
语句⑥使用装饰器data_checked与函数circle_area()建立绑定,以此为函数circle_area()增加参数有效性检测功能;
语句⑦充分利用现存的函数circle_area(),构建新的函数功能。当然你也可以像如下方式,另起炉灶:
area = radians / 360 * pi * radius ** 2
main.py模块代码如下所示:
"""
main.py : 几何图形面积计算器主程序
"""
from areas.get_area import * # ①
def enter(prompt, n=1):
"""
功能:输入n个逗号相隔的数字
参数:prompt - 提示信息
n - 输入数字的个数
"""
while True:
data_lst = input(prompt).split(',') # ②
if len(data_lst) != n:
continue
data_lst = [data.strip() for data in data_lst] # ③
break
return data_lst
def main():
# 计算圆面积
data = enter('输入园的半径 :')
print('圆面积:', circle_area(*data))
# 计算三角形面积
data = enter('输入三角形的底和高,以逗号相间:', 2)
print('三角形面积:', triangle_area(*data)) # ④
# 计算矩形面积
width, height = enter('输入矩形的宽度和高度,以逗号相间:', 2)
print('矩形面积:', rect_area(width, height)) # ⑤
# 计算扇形面积
radians, radius = enter('输入扇形的弧度和半径,以逗号相间:', 2)
print('矩形面积:', sector_area(radians, float(radius))) # ⑥
# 正方形面积
width, *other = enter('输入正方形的边长:') # ⑦
print('正方形面积:', square_area(width))
if __name__ == '__main__':
main()
重要语句说明如下:
语句①从包areas中导入模块get_area.py,仅仅在列表__all__中定义过的接口函数才能在本程序main.py成功调用;
语句②从键盘中输入多个数字,存放在列表data_lst中;
语句③使用列表推导式,过滤data_lst列表中每个数字字符串中包含的空白字符;
语句④中的函数调用triangle_area(*data),首先使用*data对列表data解包,分解为两个独立的数字字符串,以此作为triangle_area()函数的参数传递;
语句⑤演示了函数rect_area()可以正确接受两个数字字符串为参数;
语句⑥演示了函数sector_area()可以接受数字字符串、浮点数这样的参数;
语句⑦演示了列表解包的过程,获取需要的数据,舍弃无用的部分。
第4章 代码评价
通过对以上代码分析,现归纳总结如下:
菜鸟版:这种脚本编程方法通常仅适用于代码量较小的开发任务,建议是程序代码量最好不超过30行。否则随着代码行的增加,程序维护工作量也将显著增加,同时这种编码风格通常被认为不很专业,至少可以认定你现在还处在“菜鸟”级别的编程阶段。
码农版:函数编程方式充分体现了软件工程的模块化设计思想,可以提高代码重用效率,有利于程序功能扩展以及后期代码调试和维护,有利于开发团队成员间的协同开发工作。建议每个函数的语句行不超过10行代码。
大牛版:这种代码模块化组织方式具备了码农版的所有优点,通过Python包、模块和函数来组织项目代码,层次清晰,可维护性强,具有很好的可扩展性,特别适合大项目的团队协作开发。
第5章 参考资料
通过5+年的职场打拼,白小灵实现了华丽转身。其实象本文中谈及这样励志、成功逆袭的案例数不胜数,不知你如何看待这个问题呢。