背景简介
在编程的世界里,函数是构建复杂程序的基石。它们不仅能够实现特定的功能,还应当能够被重复使用,并且易于理解和维护。本章通过图片处理的案例,深入探讨了如何设计和编写既通用又可重用的函数。
Chapter 4 Modifying Pictures Using Loops
函数设计原则
在处理图片时,我们通常会用到循环来对图片的像素进行操作。本章提出了一个关键的问题:是否有必要在每个图片处理函数中都包含打开文件和制作图片的步骤?答案是否定的。更好的做法是将这些功能分离出来,让每个函数只做一件事,即所谓的“单一职责原则”。这样,函数在不同的上下文中可以被重复使用,从而提高程序的灵活性。
举例说明
通过一个简单的例子,即制作日落效果的程序,作者展示了如何通过将一个大函数拆分为多个专门化的小函数来提高代码的可读性和可维护性。例如,原来的 makeSunset
函数被拆分为 reduceBlue
和 reduceGreen
两个小函数,每个函数负责一个简单任务——减少蓝色和绿色。然后,主函数 makeSunset2
调用这两个函数来完成整个日落效果的制作。
def makeSunset2(picture):
reduceBlue(picture)
reduceGreen(picture)
def reduceBlue(picture):
for p in getPixels(picture):
value = getBlue(p)
setBlue(p, value * 0.7)
def reduceGreen(picture):
for p in getPixels(picture):
value = getGreen(p)
setGreen(p, value * 0.7)
模块化与可重用性
函数的模块化不仅让代码更加清晰,而且提高了函数的可重用性。例如, reduceBlue
和 reduceGreen
函数可以被用在任何需要减少蓝色或绿色的场景中。而且,如果未来需要为数百帧图片添加日落效果,模块化的设计可以让我们轻松地通过循环处理所有帧,而不是手动为每帧选择文件。
函数的命名和参数传递
函数的命名应当反映其功能,参数传递则提供了灵活性。在本章中,作者建议使用函数参数来传递图片或文件名,而不是在函数内部打开文件。这样做不仅可以避免重复加载相同的图片,还可以让函数在不同的上下文中被复用。
def makeSunset3(filename):
picture = makePicture(filename)
reduceBlue(picture)
reduceGreen(picture)
程序的层次分解
本章还讨论了程序的层次分解,即通过将一个复杂的问题分解为多个小问题,并为每个小问题编写一个专门的函数来解决,最终组合这些函数来完成整个任务。这种方法不仅可以使程序结构更加清晰,还便于管理和维护。
def lighten(picture):
for px in getPixels(picture):
color = getColor(px)
color = makeLighter(color)
setColor(px, color)
总结与启发
通过本章的学习,我们了解到函数设计的重要性和编写原则。函数应当简洁明了,只做一件事,并且具备良好的模块化和可重用性。此外,函数的命名和参数传递方式也对程序的易读性和灵活性有着重要影响。掌握了这些原则,我们就能编写出更加清晰、高效且易于维护的代码。
在实际应用中,我们应该从一开始就注重函数的通用性和可重用性,而不是急于编写完整应用程序。好的用户界面固然重要,但在没有充分掌握基础之前,我们应当先构建出能够被重复使用的代码。最终,这将有助于我们构建更加强大和灵活的软件系统。