一、语法格式
定义函数
def 函数名(形参列表): #函数体 return 返回值
调用函数
函数名(实参列表) # 不考虑返回值 返回值 = 函数名(实参列表) # 考虑返回值
函数的调用并不会执行函数体,但是如果要调用函数的话就必须先定义函数
二、函数参数
在函数定义的时候, 可以在 ( ) 中指定 "形式参数" (简称 形参), 然后在调用的时候, 由调用者把 "实际参数" 传递进去.。
关于参数的问题:
- 一个函数可以有一个形参, 也可以有多个形参, 也可以没有形参.
- 一个函数的形参有几个, 那么传递实参的时候也得传几个. 保证个数要匹配.
- 和C++,JAVA不同,Python传参不会局限于参数类型,可以支持多种不同类型的参数
下方代码将演示如何传参给调用的函数:
def add(a, b): print(a+b) add(1, 2)
该代码定义了一个add函数,然后在下方调用时传入1和2,然后执行函数打印出了a+b的值。
三、函数的返回值
在有参数的函数执行完后,可以对该函数处理的代码块进行处理来返回一个值。这个值可以比作参数在进入函数这个工厂加工后得到的产品,返回来被利用。
函数在使用return返回值后就跳出函数,继续执行调用函数后的代码。
- 一个函数可以有多个return语句
- 执行到 return 语句, 函数就会立即执行结束, 回到调用位置
- 如果只想关注其中的部分返回值, 可以使用 _ 来忽略不想要的返回值.
①一个函数可以有多个return语句 / return 会立即执行结束
# 判定是否是奇数 def isOdd(num): if num % 2 == 0: return False else: return True result = isOdd(10) print(result)
如该代码,总共用来两次return语句当程序遇到return语句的时候就会退出函数,所以这种条件语句中当条件被满足的时候就会执行return语句返回需要的值,然后退出函数。
②用_ 来忽略不想要的返回值.
def getPoint(): x = 10 y = 20 return x, y _, b = getPoint()
在该代码在定义的下方被调用,但是调用的时候在原本应该写变量的位置上放置了一个 “_” ,那么“_” 有什么用呢?
如果我们有一个函数有两个返回值的话,就可以用多元赋值,但是其中有一个值你不需要,那么你就可以在那个不需要值的地方用 “_” 来补充。这样,就只有自己需要的值被自己所设置的变量获取了。
四、变量作用域
def getPoint(): x = 10 y = 20 return x, y x, y = getPoint()
这个代码中函数中的x,y和下面的x,y是否是一个呢?
- 在函数内部的变量, 也称为 "局部变量"
- 不在任何函数内部的变量, 也称为 "全局变量"
当然不是。很明显,上面x,y是在在函数getPoint中的局部变量。而下面的x和y是定义的全局变量。
该例子也说明,在不同的作用域中允许用相同的变量名。
那么要如何在函数内部修改全局变量呢?
在C/C++中有指针,我们可以通过指针来进行对传入的值的修改并维持修改的值。在Python中我们用global 关键字声明,如下:
x = 20 print(x) def test(): global x x = 10 print(f'函数内部 x = {x}') test() print(f'函数外部 x = {x}')
运行结果如下:
如结果所示,在刚开使的时候我们定义x为20,然后函数被声明,并且在x在函数中用用global关键字声明全局变量x,从而使得在函数里改变x的值时,全局变量的x也收到改变。
五、链式调用
把一个函数的返回值, 作为另一个函数的参数, 这种操作称为 链式调用。
举例如下:
def isOdd(num): if num % 2 == 0: return False else: return True result = isOdd(10) print(result)
这是个判断传入的参数是否为奇数的函数,如果是返回波尔值Ture,不是返回False。
其中:
result = isOdd(10) print(result)
可以直接写成:
print(isOdd(10))
这就是链式调用的一个简单例子。
六、嵌套调用
函数内部还可以调用其他的函数, 这个动作称为 "嵌套调用"。
def a(): print("函数 a") def b(): print("函数 b") a() b() # 调用函数 b
这段代码定义了两个两个函数,在b函数中嵌套调用了a函数,所以在下面调用b函数的时候会打印出一下内容:
在函数内调用函数这种嵌套调用,相当于在函数栈帧上再开辟一片空间,在调用完函数里面的调用函数后这篇开辟的空间就会被摧毁。如果说在函数调用的函数中再次去调用另外一个函数的话那么会一直开辟空间,在一个递推的过程中创建,在一个个函数被调用完毕后会一个一个往前销毁空间,这个也就是函数栈帧的创建和销毁。
七、函数递归
递归是 嵌套调用 中的一种特殊情况, 即一个函数嵌套调用自己.
def factor(n): if n == 1: return 1 return n * factor(n - 1) result = factor(5) print(result)
上述代码中, 就属于典型的递归操作. 在 factor 函数内部, 又调用了 factor 自身,然后就会持续的调用,直到到达设定好的条件时再向后回归。
递归必须满足以下规则:
- 存在递归结束条件. 比如 if n == 1 就是结束条件. 当 n 为 1 的时候, 递归就结束了.
- 每次递归的时候, 要保证函数的实参是逐渐逼近结束条件的
如果不设置递归结束的条件的话,那么递归就会一直执行下去,导致无限循环。
八、默认值参数
Python 中的函数, 可以给形参指定默认值。
带有默认值的参数, 可以在调用的时候不传参。
代码举例:
def add(x, y, debug=False): if debug: print(f'调试信息: x={x}, y={y}') return x + y print(add(10, 20)) print(add(10, 20, True))
该代码是一个计算两个数之和的代码,此处 debug=False 即为参数默认值. 当我们不指定第三个参数的时候, 默认 debug 的取值即为 False。。
在写默认值参数时也有一定规则:
带有默认值的参数需要放到没有默认值的参数的后面
九、关键字参数
在调用函数的时候, 需要给函数指定实参。一般默认情况下是按照形参的顺序, 来依次传递实参的。
但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参。
def test(x, y): print(f'x = {x}') print(f'y = {y}') test(x=10, y=20) test(y=100, x=200)
运行结果:
可莉的话
本篇博客内容到此结束啦。函数是一个非常中要的知识,在Python程序的书写中无非就是一个个逻辑来进行拼凑实现的,其中当然少不了函数的影子~~
之后呢可莉将继续为大家带来Python的干货讲解,如果喜欢,请订阅我的《Python》专栏哦。感谢!!
以上就是可莉所了解的关于函数的知识啦,写了这么长,不知道大家有没有认真学习呢~