函数
函数基础
函数就是把具有独立功能的代码块封装起来,在需要的时候调用。
def funtion_name():
函数名可以由字母、下划线、数字组成
不能以数字开头,不能和关键字重名
调用函数的语句不能出现在函数上方。
在给函数增加注释的时候,可以在函数下方添加三个引号然后注释。
def say_hello():
"""打招呼"""
这样在调用的时候,可以点击函数名,Ctrl + Q查看注释。
函数可以传递参数,用于函数处理。
形参:定义函数时的参数,用来接收参数,在函数内部作为变量使用。函数内的形参相当于一个局部变量。
实参:调用函数时的参数,用来把数据传递到函数内部。
函数可以使用return
关键字返回结果。
调用一方可以使用变量来接收函数返回的结果。
return
表示返回,后续代码都不会被执行。
函数可以嵌套调用,形参可以层层传递到函数。
函数的高级用法
在函数中,可以使用元组一次返回多个变量
return (temp, wetness)
并且,如果函数返回的类型是元组,小括号可以省略
return temp, wetness
使用print
打印结果,会发现打印出来是一个元组。
def measure():
temp = 30
wetness = 40
return temp, wetness
result = measure()
print(result)
要获取返回的元组内的值,有两种方法:
print(result[0])
print(result[1])
gl_temp, gl_wetness = measure()
print(gl_temp)
print(gl_wetness)
很明显,通过定义常量来接收函数返回的元组元素的值,更方便我们后续的调用。使用变量接收函数的结果时,变量的个数应该和元组中元素的个数保持一致,否则程序会报错。
a和b交换值的三种解法:
c=a
a=b
b=c
a=a+b
b=a-b
a=a-b
a,b=(b, a)
因为当右边是元组时,小括号可以省略,所以:
a,b=b, a
在函数内部,通过对形参使用赋值语句,不会改变全局变量的值,不管该全局变量的值是不是可变类型数据。这和函数的执行顺序有关,全局变量这个标签从来没有被从它的值上撕下来过。在函数内部通过对形参使用赋值语句,相当于将形参这个局部变量从全部变量的值上撕下来贴到了新赋予的值上。
如果函数传递的参数是可变类型,在函数内部使用方法修改了数据的内容,同样会影响到外部数据。因为调用方法并不会修改函数内部局部变量的引用,而是直接对可变类型的数据进行修改。
在python中,+=
操作本质上是先相加再赋值的操作,但是如果列表变量调用+=
本质上是在执行列表变量的extend
方法,不会修改变量的引用,而是直接对列表的值进行修改,其结果和num_list = num_list + num_list
的结果不同。
def demo(num, num_list):
num += num
num_list += num_list
print(num)
print(num_list)
gl_num = 9
gl_list = [1, 2, 3]
demo(gl_num, gl_list)
print(gl_num)
print(gl_list)
代码执行的结果是:
18
[1, 2, 3, 1, 2, 3]
9
[1, 2, 3, 1, 2, 3]
缺省参数
函数可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数。在调用函数时,如果没有传入缺省参数的值,则在函数内部使用定义函数时指定的默认值。
比如如果一个班级内男生较多:
def print_info(name, title="", gender=True):
gender_text = "男生"
if not gender:
gender_text = "女生"
print("%s 是 %s" % (name, gender_text))
print_info("小美", gender=False)
在定义函数时,带有默认值的缺省参数应该在参数列表的末尾。
在调用具有多个缺省参数的函数时,需要指定参数名。
多值参数
如果一个函数需要处理的参数个数是不确定的,这个时候就可以使用多值参数。
在python中有两种多值参数:
参数名前增加一个 * 可以接收元组
参数名前增加两个 * 可以接收字典
一般在给多值参数命名时,习惯使用以下两个名字:
*args
—存放元组参数
**kwargs
—存放字典参数
args
是 arguments的缩写,有变量的含义
kw
是 keyword的缩写,kwargs可以记忆键值对参数
def demo(num, *args, **kwargs):
print(num)
print(args)
print(kwargs)
demo(1, 2, 3, 4, name = "小明", age = 18, gender = True)
执行结果是:
1
(2, 3, 4)
{'name':'小明', 'age':18, 'gender':True}
传入任意多个数字进行求和:
def sum_numbers(*args):
num = 0
print(args)
for n in args:
num += n
return num
result = sum_numbers(2, 4, 5)
print(result)
元组和字典的拆包:
在元组变量前加一个*,在字典变量前加两个*,就可以将变量直接传给带有多值参数的函数。这种方法成为拆包。
def demo(*args, **kwargs):
print(args)
print(kwargs)
gl_nums = (1, 3, 4)
gl_xiaoming = {"name":"小明", "age":18}
demo(*gl_nums, **gl_xiaoming)
上面在调用函数时如果传入的实参前面不加*,那么gl_nums
和gl_xiaoming
就会被当做元组的两个变量被传入到形参args
中去,而打印出来的kwargs
就会是一个空字典。如果不使用拆包,就需要吧gl_nums
和gl_xiaoming
中的元素一个个拿出来一起填到函数括号中当做实参传递进去。
函数的递归
函数调用自身的编程技巧成为递归。
递归的特点:
函数内部代码是相同的,但是针对参数的不同,处理的结果不同。
当参数满足一个条件时,函数不再执行。这个条件非常重要,通常被称为递归的出口,否则会出现死循环。
def sum_numbers(num):
print(num)
if num == 1:
return
sum_numbers(num-1)
print("完成%d" % num)
sum_numbers(3)
执行结果是:
3
2
1
完成2
完成3
可以用递归完成1到n的累加:
def sum_number(num):
if num == 1:
return 1
temp = sum_number(num-1)
return num + temp
result = sum_number(100)
print(result)
这是递归求和的一种用法,但是如果传入的实参过大,会提示递归深度错误。
f(x) = x + f(x-1)
函数的大致内容就这些,下一篇博文要写面向对象。