Python函数
函数
-
函数的定义
-
def 函数名(参数列表): 函数体(代码块) [return 返回值]
-
函数名就是标识符,命名要求一样
-
语句块必须缩进,约定4个空格
-
Python的函数若没有return语句,会隐式返回一个None值
-
定义中的参数列表被称为形式参数,只是一种符号表达(标识符),简称形参
-
-
函数调用
-
函数定义,只是声明了一个函数,他不能被执行,需要调用执行
-
调用的方式,就是函数名后加上小括号,如有必要在括号内写上参数
-
调用时写的参数就是实际参数,是实实在在的传入的值,简称实参
-
def add(x, y): result = x + y # 函数体 return result # 返回值 out = add(4, 5) # 函数调用,可能有返回值,使用变量接收这个返回值 print(out) # print函数加上括号也是调用
-
定义需要在调用前,也就是说调用时,已经被定义过了,否则抛NameError异常
-
函数是可调用的对象,callable()
-
函数参数
- 函数在定义时要约定好形式参数,调用时也提供足够的实际参数,一般来说,形参和实参个数要一致(可变参数除外)
传参方式
- 位置传参
- 定义时,def f(x, y, z), 调用使用f(1, 3, 5),按照参数定义顺序传入实参
- 关键字参数
- 定义时,def(x, y, z),调用使用f(x=1, y=3, z=5),使用形参的名字来传入实参的方式,如果使用了形参名字。那么传参顺序就可和定义顺序不同
- 要求位置参数必须在关键字参数之前,位置参数是按位置对应的
参数缺省值
缺省值也称为默认值,可以在函数定义时,为形参增加一个缺省值。其作用:
-
参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
-
参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用
-
def add(x=4, y=5): return x+y add(y=8, 4) # 报错 add(11, x=20) # 报错
可变参数
- 可变位置参数
- 在形参前使用*表示该形参是可变位置参数,可以接受多个实参
- 它将收集来的实参组织到一个tuple中
- 可变关键字参数
- 在形参前使用**表示该形参是可变关键字参数,可以接受多个关键字参数
- 它将收集来的实参名称和值,组织到一个dict中
- 总结:
- 有可变位置参数和可变关键字参数
- 可变位置参数在形参前使用一个*
- 可变关键字参数在形参前使用**
- 可变位置参数和可变关键字参数都可以收集若干个实参,可变位置参数收集形成一个tuple,可变关键字参数收集形成一个dict
- 混合使用参数的时候,普通参数需要放到参数列表前面,可变参数要放到参水列表后面,可变位置参数需要在可变关键字参数之前
keyword-only参数
-
def fn(*args, x, y, **kwargs): print(x, y, args, kwargs, sep='\n', end='\n\n') fn(3, 5) # 错 fn(3, 5, 7) # 错 fn(3, 5, a=1, b='abc') # 错 fn(3, 5, y=6, x=7, b='abc') # 正确
-
Python3之后,新增了keyword-only参数
-
keyword-only参数,在形参定义时,在一个*之后,或一个可变位置参数之后,出现的普通参数,就已经不是普通的参数了,称为keyword-only参数
参数的混合使用
-
# 可变位置参数、keyword-only参数、缺省值 def fn(*args, x=5): print(x) print(args) fn() # 等价于fn(x=5) fn(5) # 返回一个5和一个元组(5,) fn(x=6) # x=6 fn(1,2,3,x=10) # 返回(1,2,3)和10
参数规则
- 参数列表参数一般顺序是:普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数
- 代码应该易读易懂,而不是为难别人
- 请按照书写习惯定义函数参数
参数解构
-
def add(x, y): print(x, y) return x + y add(4, 5) # 9 add((4, 5)) # 报错 少一个参数 t = 4, 5 add(t[0], t[1]) # 9 add(*t) # 9 add(*(4, 5)) # 9 add(*[4, 5]) # 9 add(*{ 4, 5}) # 9 add(*range(4, 6)) # 9 add(*{ 'a':10, 'b':11}) # 'ab' add(**{ 'a':10, 'b':11}) # 报错 add(**{ 'x':100, 'y':110}) # 210
-
在给函数提供实参的时候,可以在可迭代对象前使用*或者**来进行结构的解构,提取出其中所有元素作为函数的实参
-
使用*解构成位置传参
-
使用**解构成关键字传参
-
提取出来的元素数目要和参数的要求匹配
-
def add(*iterable): result = 0 for x in iterable: result += x return result add(1, 2, 3) # 6 add(*[1, 3, 5]) # 9 add(*range(5)) # 10
-
函数返回值
-
# return语句之后可以执行吗 def showplus(x): print(x) return x + 1 print('~~end~~') showplus(5) # 不会执行
-
# 多条return语句都会执行吗 def showplus(x): print(x) return x + 1 return x + 2 showplus(5) # 不会执行
-
# 下例多个return可以执行吗 def guess(x): if x > 3: return '>3' else: return '<=3' print(guess(10)) # 只执行一条
-
总结:
- Python函数使用return语句返回“返回值”
- 所有函数都有返回值,如果没有return语句,隐式调用return None
- return语句并不一定是函数的语句块的最后一条语句
- 一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执行到,隐式调用return None
- 如果必要,可以显示调用return None,可以简写为return
- 如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其他语句就不会被执行了
- 返回值的作用:结束函数调用,返回“返回值”
-
# 返回了多个值吗? def f(): return 1, 3, 5 f() # (1, 3, 5)返回了一个元组
- 函数不能同时返回多个值
- return1,3,5看似返回多个值,实际上隐式的被Python封装成了一个元组
函数作用域
作用域
一个标识符的可见范围,这就是标识符的作用域。一般常说的是变量的作用域
-
def foo(): x = 10 print(x) -->报错
- 上例中,x不可以被访问到。原因在于函数是一个封装,他会开辟一个作用域,x变量被限制在这个作用域中,所以在函数外部x变量不可见
- 每一个函数都会开辟一个作用域
-
作用域分类
-
全局作用域
- 在整个程序运行环境中都可见
- 全局作用域中的变量称为全局变量
-
局部作用域
-
在函数、类的内部可见
-
局部作用域中的变量称为局部变量,其使用范围不能超过其所在的局部作用域
-
也称本地作用域local
-
# 局部变量 def fn1(): x = 1 # 局部作用域,x为局部变量,使用范围在fn1内 def fn2(): print(x) # x能被打印吗?不能 print(x) # x不能被打印
-
# 全局变量 x = 5 # 全局变量,也在函数外定义 def f00(): print(x) foo() # 5
-
一般来说,外部作用域变量可以在函数内部可见,可以是哦也使用
-
反过来,函数内部的局部变量,不能在函数外部看到
-
-
-
函数嵌套
-
def outer(): def inner(): print('inner') print('outer') inner(
-