python入门教程(三)——函数
本教程根据《python编程快速上手》制作,如需转载,请注明出处。
函数的一个主要目的就是将需要多次执行的代码放在一起。这样如果需要修改就会很方便,不用每个地方都要改,只要该函数内部即可。
一、定义函数的格式
需要以下几点:
- def关键字
- 函数名和括号,可能还包括参数
- 冒号
- 缩进的函数体
例子1:
执行结果:
第一行是 def 语句,它定义了一个名为 hello()的函数。def 语句之后的代码块是函数体。函数之后的 hello()语句行是函数调用。
例子2:
执行结果:
例子2定义了一个带参数的函数。在这个程序的 hello()函数定义中,有一个名为 name 的变元。“变元”是一个变量,当函数被调用时,参数就存放在其中。当调用函数时,就把传入的参数赋值给这个“变元”。
二、返回值和return语句
一般来说,函数调用求值的结果,称为函数的“返回值”。
用 def 语句创建函数时,可以用 return 语句指定应该返回什么值。return 语句包含以下部分:
- return 关键字;
- 函数应该返回的值或表达式
如果在 return 语句中使用了表达式,返回值就是该表达式求值的结果。
例子1:
请注意,因为可以将返回值作为参数传递给另一个函数调用。
因此最后三行可以写成一行。如下:
三、None值
在 Python 中有一个值称为 None,它表示没有值。None 是 NoneType 数据类型的唯一值(其他编程语言可能称这个值为 null、nil 或 undefined)。就像布尔值 True和 False 一样,None 必须大写首字母 N。
在幕后,对于所有没有 return 语句的函数定义,Python 都会在末尾加上 return None。
四、关键字参数和print()
大多数参数是由它们在函数调用中的位置来识别的。
例如:
我把random.randint中小的数放在后面,就会报错。
但是,“关键字参数”是由函数调用时加在它们前面的关键字来识别的。关键字参数通常用于可选变元。这在后面会碰到很多。
例如,print()函数有可选的变元 end 和 sep,分别指定在参数末尾打印什么,以及在参数之间打印什么来隔开它们。
例子1:
执行结果:
这两个字符串出现在独立的两行中,因为 print()函数自动在传入的字符串末尾添加了换行符。但是,可以设置 end 关键字参数,将它变成另一个字符串。
例子2:
执行结果:
例子3:
如果向 print()传入多个字符串值,该函数就会自动用一个空格分隔它们。
例子4:
你可以传入 sep 关键字参数,替换掉默认的分隔字符串。就如同上面的逗号分隔开一样。
五、局部和全局作用域
这又是老生常谈的话题了。以前看C语言看了好多遍,python之中的原理也是类似的。
在被调用函数内赋值的变元和变量,处于该函数的“局部作用域”。在所有函数之外赋值的变量,属于“全局作用域”。处于局部作用域的变量,被称为“局部变量”。处于全局作用域的变量,被称为“全局变量”。一个变量必是其中一种,不能既是局部的又是全局的。
可以将“作用域”看成是变量的容器。当作用域被销毁时,所有保存在该作用域内的变量的值就被丢弃了。只有一个全局作用域,它是在程序开始时创建的。如果程序终止,全局作用域就被销毁,它的所有变量就被丢弃了。否则,下次你运行程序的时候,这些变量就会记住它们上次运行时的值。
一个函数被调用时,就创建了一个局部作用域。在这个函数内赋值的所有变量,存在于该局部作用域内。该函数返回时,这个局部作用域就被销毁了,这些变量就丢失了。下次调用这个函数,局部变量不会记得该函数上次被调用时它们保存的值。
1、局部变量不能在全局作用域内使用
例子1:
执行结果:
所以,如果在全局变量中调用局部变量中的参数,就会报错,名称没有定义。因为函数调用的时候,eggs变量被创建,调用完成之后,eggs变量就销毁了。因此全局变量中无法再进行访问了。
2、局部作用域不能使用其他局部作用域内的变量
例子2:
调用spam()函数时的eggs是其内部定义的那个99的值,与bacon中定义的eggs没有关系,并不受其影响。
3、全局变量可以在局部作用域中读取
例子3:
首先调用spam()函数,打印全局变量中的eggs,然后调用第5行的print()函数打印出结果。
以上,说明了局部作用域可以访问全局变量,但这是有条件的。
4、名称相同的局部变量和全局变量
例子4:稍微改了一下例子3的程序
全局作用域定义了一个eggs,spam()函数的局部作用域内也定义了一个eggs,然后spam()函数内的print()函数打印的是50,说明同名的局部变量屏蔽了同名的全局变量在局部中的访问。
5、global关键字
如果需要在一个函数内修改全局变量,就使用 global 语句。
例子5:
执行结果:
自己体会下,不是全局作用域访问量局部变量,而是在局部作用域内通过声明global,进而修改了全局变量。
6、如何区*部变量和全局变量
六、异常处理
先举个例子:
执行结果:
也就是除数为0的那个错误。
然而一般用户是看不懂这些错误的,你好不容易开发个程序,结果用户已用,就出这种贼长的bug提示,还看不懂,这很不友好。聪明的程序员应该事先检查可能出错的地方,并作出相应的处理。然后就需要try 和except这对关键字了。
错误可以由 try 和 except 语句来处理。那些可能出错的语句被放在 try 子句中。如果错误发生,程序执行就转到接下来的 except 子句开始处。
再看下面这个例子。
执行结果:
这样是不是跟刚才比,友好多了。