Python学习笔记四——函数
关键字def和定义
定义函数使用 def 关键字:
def 函数名(参数列表):
函数体
return [表达式]
参数与作用域
python 函数的参数传递:
- 不可变类型:
类似值传递,如:整数、字符串、元组。如fun(a)
,传递的只是a
的值,没有影响a
对象本身。比如在fun(a)
内部修改a
的值,只是修改另一个复制的对象,不会影响a
本身。 - 可变类型:
类似引用传递,如:列表、字典。如fun(la)
,则是将la
真正的传过去,修改后fun
外部的la
也会受影响。
参数类型:
- 必需参数:
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。# 打印任何传入的字符串,参数str是必需的 def printme(str): print(str) return # 调用printme函数 printme('hi')
- 关键字参数:
函数调用使用关键字参数来确定传入的参数值,调用时参数的顺序允许与声明时不一致。# 打印传入的参数name、age def printinfo(name, age): print("名字: ", name) print("年龄: ", age) return # 调用printinfo函数 printinfo(age=50, name="runoob")
- 默认参数:
调用函数时,如果没有传递参数,则会使用默认参数,默认参数必须指向不变对象。# 打印传入的参数name、age、nationality def printinfo(name, age, nationality="中国"): print("名字: ", name) print("年龄: ", age) print("国籍: ", nationality) return # 调用printinfo函数 printinfo(age=50, name="runoob") printinfo(name="Wendy", age=35, nationality="美国")
- 可变参数:
需要一个函数能处理比当初声明时更多的参数。
(1).带一个星号 *的参数:def functionname([formal_args,] *var_args_tuple ): "函数_文档字符串" function_suite return [expression]
加了星号 * 的参数会以元组(
tuple
)的形式导入,存放所有未命名的变量参数。# vartuple以元组形式存放所有未命名的变量参数 def printinfo(arg1, *vartuple): print("输出: ") print(arg1) for var in vartuple: print (var) return # 调用printinfo 函数 printinfo(10) printinfo(70, 60, 50)
在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去。
(2).带两个星号 **的参数:def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum # 将list前面加*,变成可变参数传入 nums = [1, 2, 3] calc(*nums)
def functionname([formal_args,] **var_args_dict ): "函数_文档字符串" function_suite return [expression]
两个星号 ** 的参数会以字典的形式导入。
# vardict会以字典的形式导入 def printinfo(arg1, **vardict): print("输出: ") print(arg1) print(vardict) # 调用printinfo 函数 printinfo(1, a=2, b=3)
在
dict
前面加两个**号,把dict
的元素变成可变参数传进去。**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw) extra = {'city': 'Beijing', 'job': 'Engineer'} person('Jack', 24, **extra)
- 命名关键字参数:
声明函数时,参数中星号*
可以单独出现,单独出现星号*
后的参数必须用关键字传入,以下函数定义f
,在调用时必须使用f(1,2,c=3)
的方式传入参数名。def f(a,b,*,c): return a+b+c
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符
*
了。def person(name, age, *args, city, job): print(name, age, args, city, job)
参数定义的顺序必须是:必需参数、默认参数、可变参数、命名关键字参数和关键字参数。对于任意函数,都可以通过类似
func(*args, **kw)
的形式调用它,无论它的参数是如何定义的。*args
是可变参数,args
接收的是一个tuple
;**kw
是关键字参数,kw
接收的是一个dict
。
作用域:
Python的作用域一共有4种,分别是:
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内置作用域(内置函数所在模块的范围)
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。当内部作用域想修改全局变量,就要用到
global
关键字;当内部作用域想修改嵌套作用域(enclosing
作用域,外层非全局作用域)中的变量,就要用到nonlocal
关键字。
返回值
Python的函数返回多值其实就是返回一个tuple
,不带参数值的return
语句返回None
。
匿名函数
使用 lambda
来创建匿名函数,lambda
函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数:lambda [arg1 [,arg2,.....argn]]:expression
。
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))