无参定义函数
1. 语法
def function_name():
expressions
Python 使用def
开始函数定义,紧接着是函数名,括号内部为函数的参数,内部为函数的 具体功能实现代码,如果想要函数有返回值, 在 expressions
中的逻辑代码中用return
返回。
2. 实例
def function():
print('This is a function')
a = 1+2
print(a)
上面我们定义了一个名字为function
的函数,函数没有接收参数,所以括号内部为空,紧接着就是 函数的功能代码。如果执行该脚本,发现并没有输出任何输出,因为我们只定义了函数,而并没有执行函数。 这时我们在 Python 命令提示符中输入函数调用 function()
, 注意这里调用函数的括号不能省略。那么 函数内部的功能代码将会执行,输出结果:
This is a function
3
带参定义函数
1. 语法
def function_name(parameters):
expressions
2. 实例
def func(a, b):
c = a+b
print('the c is ', c)
在这里定义的一个函数,其参数就是两个数值,函数的功能就是把两个参数加起来。运行脚本后,在 Python 提示符内调用函数 func
, 如果不指定参数 func()
, 那么将会出错; 输出 func(1, 2)
,将 a=1
, b=2
传入函数,输出 the c is 3
。所以在调用函数时候,参数个数和位置一定要按照函数定义。如果我们忘记了函数的参数的位置,只知道各个参数的名字,可以在 函数调用的过程中给指明特定的参数 func(a=1, b=2)
, 这样的话,参数的位置将不受影响,所以 func(b=2,a=1)
是同样的 的效果。
函数默认参数
1. 语法
def function_name(para_1,...,para_n=defau_n,..., para_m=defau_m):
expressions
函数声明只需要在需要默认参数的地方用=
号给定即可, 但是要注意所有的默认参数都不能出现在非默认参数的前面。
2. 实例
def sale_car(price, color='red', brand='carmy', is_second_hand=True):
print('price', price,
'color', color,
'brand', brand,
'is_second_hand', is_second_hand,)
在这里定义了一个 sale_car
函数,参数为车的属性,但除了 price 之外,像 color
, brand
和 is_second_hand
都是有默认值的,如果我们调用函数 sale_car(1000)
, 那么与 sale_car(1000, 'red', 'carmy', True)
是一样的效果。当然也可以在函数调用过程中传入特定的参数用来修改默认参数。通过默认参数可以减轻我们函数调用的复杂度。
注意:默认值放在非默认值之后
3. 进阶
3.1 自调用
如果想要在执行脚本的时候执行一些代码,比如单元测试,可以在脚本最后加上单元测试 代码,但是该脚本作为一个模块对外提供功能的时候单元测试代码也会执行,这些往往我们不想要的,我们可以把这些代码放入脚本最后:
if __name__ == '__main__':
#code_here
如果执行该脚本的时候,该if
判断语句将会是 True
,那么内部的代码将会执行。 如果外部调用该脚本,if
判断语句则为False
,内部代码将不会执行。
单元测试举例
①首先定义了一个测试函数:namefunction.py
def get_formmed_name(first, last):
"""该函数根据姓和名生成一个完整的姓名"""
full_name = first + ' ' + last
return full_name.title()
②然后编写了一个测试该函数的模块:names.py
from name_function import get_formmed_name
"""该文件用来测试姓名生成函数"""
print "Enter 'q' to quit any time."
while True:
first = raw_input("\nEnter first name:")
if first == 'q':
break
last = raw_input("Enter last name:")
if last == 'q':
break
formatted_name = get_formmed_name(first,last)
print "Formmated name:",formatted_name
通过测试,name_function中的函数可以实现其功能。
③最后是单元测试和测试用例的编写。 test_name_function.py
import unittest
from name_function import get_formmed_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py"""
def test_first_last_name(self):
"""能够正确处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formmed_name('janis','joplin')
self.assertEqual(formatted_name,'Janis Joplin')
#注意这个地方,我在Python 2.7的版本中直接调用书上的主函数
#unittest.main()时程序无法通过,而改用以下调用方式即可
if __name__ == '__main__':
unittest
通过对以上单元测试模块分析:
- 导入单元测试类
unittest
- 导入要测试的函数,本例为
name_function
模块中的get_formatted_name()
函数 - 创建一个继承于
unittest.TestCase
的类 - 在类中定义一系列方法对函数的行为进行不同方面的测试,需要注意的是一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用
assertEqual
、assertRaises
等断言方法判断程序执行结果和预期值是否相符。
3.2 可变参数
顾名思义,函数的可变参数是传入的参数可以变化的,1个,2个到任意个。当然可以将这些 参数封装成一个list
或者 tuple
传入,但不够 pythonic
。使用可变参数可以很好解决该问题,注意可变参数在函数定义不能出现在特定参数和默认参数前面,因为可变参数会吞噬掉这些参数。
def report(name, *grades):
total_grade = 0
for grade in grades:
total_grade += grade
print(name, 'total grade is ', total_grade)
定义了一个函数,传入一个参数为name
, 后面的参数*grades
使用了*
修饰,表明该参数是一个可变参数,这是一个可迭代的对象。该函数输入姓名和各科的成绩,输出姓名和总共成绩。所以可以这样调用函数 report('Mike', 8, 9)
,输出的结果为 Mike total grade is 17
, 也可以这样调用 report('Mike', 8, 9, 10)
,输出的结果为 Mike total grade is 27
3.3 关键字参数
关键字参数可以传入0个或者任意个含参数名的参数,这些参数名在函数定义中并没有出现,这些参数在函数内部自动封装成一个字典(dict).
def portrait(name, **kw):
print('name is', name)
for k,v in kw.items():
print(k, v)
定义了一个函数,传入一个参数 name
, 和关键字参数 kw
,使用了**
修饰。表明该参数是关键字参数,通常来讲关键字参数是放在函数参数列表的最后。如果调用参数 portrait('Mike', age=24, country='China', education='bachelor')
输出:
name is Mike
age 24
country China
education bachelor
通过可变参数和关键字参数,任何函数都可以用 universal_func(*args, **kw) 表达。
全局变量、局部变量
局部变量
在 def
中, 我们可以定义一个局部变量, 这个变量 a
只能在这个功能 fun
中有效, 出了这个功能, a
这个变量就不是那个局部的 a
.
def fun():
a = 10
print(a)
return a+100
print(fun())
"""
10
110
"""
下面这个例子就验证了如果在 fun
外面调用a
, 会报错, 这表明外面的这个 print(a)
不能找到那个局部的 a
, 只有全局变量再能在外面被调用, 比如 APPLE
.
APPLY = 100 # 全局变量
def fun():
a = 10 # 局部变量
return a+100
print(APPLE) # 100
print(a) # 报错, 不能拿到一个局部变量的值
全局变量
首先我们在外部定义一个全局变量 a=None
, 然后再 fun()
中声明 这个a
是来自外部的 a
. 声明方式就是 global a
APPLY = 100 # 全局变量
a = None
def fun():
global a # 使用之前在全局里定义的 a
a = 20 # 现在的 a 是全局变量了
return a+100
print(APPLE) # 100
print('a past:', a) # None
fun()
print('a now:', a) # 20