4.2.3 用函数增强程序的通用性
我们说过,程序 4.4 在减少重复代码和模块化两方面已经做得很好,但这并不意味着该 程序在各方面都已经完美。例如,如果我们希望换用字符"^"再画一棵树,以便比较哪个更 好看些,该如何做呢?显见的做法是仿照用"*"画树的代码重写画树冠的函数,而树干部分 可以重用。于是得到下面的代码:
【程序 4.5】tree5.py
def treetop1():
print " *"
print " ***"
print " *****"
print "*******"
def treetop2():
print " ^"
print " ^^^"
print " ^^^^^"
print "^^^^^^^"
def star_treetop():
treetop1()
treetop1()
def caret_treetop():
treetop2()
treetop2()
def treetrunk():
print " #"
print " #"
print " #"
def main():
star_treetop()
treetrunk()
print
caret_treetop()
treetrunk()
main()
此版本的执行结果如下:
*
***
*****
*******
*
***
*****
*******
#
#
#
^
^^^
^^^^^
^^^^^^^
^
^^^
^^^^^
^^^^^^^
#
#
#
虽然程序 4.5 满足了功能需求,但是从程序设计角度说是很笨拙的,因为这是一种“头 痛医头脚痛医脚”的方法,即为每一种特殊情形创建新的代码。更好的做法是用一个一般的 函数来处理所有特殊情形。鉴于 treetop1 和 treetop2 的非常类似,我们可以从他们抽 象出一个通用的画树冠的函数,使得该函数能够取代 treetop1 和 treetop2。
函数的通用性可以通过引入参数(parameter)来实现。要理解参数的作用,可以简单地与数学函数的自变量进行类比。以函数 f(x) = x2 为例,对于给定的自变量值 10,函数计算 出函数值 f(10) = 100;换不同的自变量值 20,则函数又计算出另一个函数值 f(20) = 400。编 程语言中的函数参数具有类似的行为,输入不同的参数值,则函数执行后可产生不同的结果。
下面我们设计一个通用的画树冠的函数 treetop(ch),其中参数 ch 表示用来作画的 字符。为了控制树的形状,函数定义中使用了字符串格式化运算。
>>> def treetop(ch):
print " %s" % (ch)
print " %s" % (3 * ch)
print " %s" % (5 * ch)
print "%s" % (7 * ch)
在交互环境定义了函数 treetop(ch)后,我们接着来测试它的效果。下面是测试例子:
>>> treetop('*')
*
***
*****
*******
>>> treetop('^')
^
^^^
^^^^^
^^^^^^^
>>> treetop('A')
A
AAA
AAAAA
AAAAAAA
可见函数 treetop(ch)确实具有通用性,只要为它的参数提供一个字符值,就能用该字符 画出树冠形状。下面我们利用 treetop(ch)函数来改写程序 4.5:
【程序 4.6】tree6.py
def treetop(ch):
print " %s" % (ch)
print " %s" % (3 * ch)
print " %s" % (5 * ch)
print "%s" % (7 * ch)
def star_treetop():
treetop("*")
treetop("*")
def caret_treetop():
treetop("^")
treetop("^")
def treetrunk():
print " #"
print " #"
print " #"
def main():
star_treetop()
treetrunk()
print
caret_treetop()
treetrunk()
main()
此版本的执行结果和程序 4.5 完全一样,但是比较两者的代码会发现,程序 4.6 将程序 4.5
中的两个函数合二为一,增强了通用性。以后如果想换用其他字符画树,修改程序 4.6 比修
改程序 4.5 要简单得多。