编程入门07:Python函数定义
by 星辉
Posted on 2018年03月20日周二 at 09:01下午 in 教程
你己经接触过很多的函数,现在让我们尝试定义自己的函数——这需要使用def关键字。函数定义好后即可调用,以下是在交互模式中定义并调用了一个非常简单的函数:
In [1]: def welcome(): ...: """输出欢迎信息""" ...: print("欢迎光临!") ...: In [2]: welcome() 欢迎光临! In [3]: type(welcome) Out[3]: function In [4]: help(welcome) Help on function welcome in module __main__: welcome() 输出欢迎信息 In [5]:
你可以发现函数并不神秘,只是把一段程序定义为一个对象以便重复使用而已——另外请注意用三个引号引起来的字符串,这样的字符串允许分行,当放在函数体最前面时则会成为这个函数的“文档字符串”(Docstring),help函数所显示的帮助信息就来自相应对象的文档字符串。至于函数返回值的功能则是使用return关键字实现的,如果函数没有return语句,则默认没有返回值。
接下来让我们再用海龟绘图来练习复杂一些的函数:新建文件turtledraw.pyw,定义一个五角星函数star5p,并在之后的代码中调用这个函数:
"""自定义的海龟绘图函数集 """ import turtle as tt def star5p(): """画一颗五角星 """ t = tt.Turtle() # 生成一个单独的海龟对象 t.hideturtle() t.speed(0) t.color("purple") t.penup() t.begin_fill() # 启用填充区域 cnt = 0 while cnt < 5: t.forward(20) t.left(72) t.forward(20) t.right(144) cnt += 1 t.end_fill() tt.TurtleScreen._RUNNING = True # 画一个五边形 tt.color("pink") tt.penup() tt.begin_fill() tt.setpos(-25, -75) tt.pendown() cnt = 0 while cnt < 5: tt.forward(100) tt.left(72) cnt += 1 tt.end_fill() star5p() # 调用函数画一颗五角星 tt.done()
函数在所属模块空间内分隔出一个子空间——例如star5p函数生成了一个单独的海龟对象变量t。这个变量t只在star5p函数中存在,离开这个函数就不能再使用了,而star5p函数内则可以使用在外面定义的海龟对象变量tt——变量存在并发挥作用的范围称为变量的“作用域”(Scope)。
上面程序中定义的star5p函数很不灵活,不管调用多少次都只从原点开始画一颗同样的五角星,让我们来加以改进——定义函数时加上参数变量列表:x和y变量指定五角星的坐标位置;size变量指定五角星的边长,angle变量指定五角星的倾角,在函数调用时作为参数传入的值将赋给这些变量,参数变量作用域限于函数内部:
"""自定义的海龟绘图函数集 """ import turtle as tt def star5p(x, y, size=20, angle=0): """在指定位置画一颗五角星 """ t = tt.Turtle() # 生成一个单独的海龟对象 t.hideturtle() t.speed(0) t.color("white") t.penup() t.setpos(x, y) t.right(angle) t.begin_fill() # 启用填充区域 cnt = 0 while cnt < 5: t.forward(size) t.left(72) t.forward(size) t.right(144) cnt += 1 t.end_fill() def test(): """测试绘图函数:随机画十颗五角星 """ from random import randint tt.TurtleScreen._RUNNING = True tt.setup(width=720, height=480, startx=None, starty=None) tt.hideturtle() tt.speed(0) tt.bgcolor("purple") tt.penup() cnt = 0 while cnt < 10: x = randint(-300, 300) y = randint(-200, 200) s = randint(10, 30) a = randint(0, 72) star5p(x, y, s, a) # 带参数调用五角星函数 cnt += 1 tt.done() if __name__ == "__main__": # 运行模块时调用测试绘图函数 test()
现在的star5p函数有4个参数,前两个参数在调用时是必须传入的,后两个参数在定义时赋了默认值,在调用时如果不传入就会使用默认值——如果只传入三个参数,则第三个参数必须使用“变量名=值”的形式例如“angle=10”以避免歧义。上面的程序还定义了一个test函数,实现随机绘制十颗五角星:
程序文件turtledraw.pyw实际上就是一个自定义模块,可以使用import语句引入。模块在主名称空间中运行时__name__变量的取值是默认的"__main__",被引入时__name__变量的取值则是模块名"turtledraw",模块就可以据此判断自己是被运行还是被引入,从而决定是否执行test函数——推荐大家今后也都使用这样的模式,整个程序由独立的函数构成,并在最后调用一个作为入口的“主函数”。
In [1]: import turtledraw as td In [2]: help(td) Help on module turtledraw: NAME turtledraw - 自定义的海龟绘图函数集 FUNCTIONS star5p(x, y, size=20, angle=0) 在指定位置画一颗五角星 test() 测试绘图函数 FILE d:\test\pystudy\turtledraw.pyw In [3]: td.__name__ Out[3]: 'turtledraw' In [4]:
编程小提示:程序项目
任何IDE都有“工程”或“项目”(Project)的概念,实际上就是建立专门的文件夹来组织相关的程序文件。例如Spyder中创建项目是在主菜单中选择Projects > New Project...,你可以创建一个名为pyStudy的项目,把你编写的所有程序文件都放进去。以后Spyder启动时会自动打开最近的项目并将“工作目录”设为项目所在的文件夹,而不再使用默认的用户文件夹。