Python---函数
目录
函数
函数格式
函数参数的定义
注意:
函数的返回值
一个函数可以有多个return语句
多元赋值
可以使用_(下斜线)来忽略不想要的值
变量作用域
global关键字
函数执行过程
调试、断点
链式调用
嵌套调用
栈帧:
函数递归
注意:
递归的优点
递归的缺点
参数默认值
注意:
关键字参数:
函数
编程中的函数,是一段可以被重复使用的代码片段。
函数格式
def 函数名 ( 形参列表 ):函数体return 返回值
函数执行到return就意味着执行完了,return后面的值,就是函数的返回值~
return语句并不是必须的,可以有,也可以没有~~
函数的调用
函数名 ( 实参列表 ) //实际参数,简称实参,此处写的实参的个数要和形参的个数匹配返回值 = 函数名 ( 实参列表 )
Python中要求,函数定义写在前面,函数调用写在后面~~先定义,后调用!!!否则就会警告
相反的案例:
函数参数的定义
在函数定义的时候 , 可以在 ( ) 中指定 " 形式参数 " ( 简称 形参 ), 然后在调用的时候 , 由调用者把 " 实际参数 " (简称 实参 ) 传递进去。这样就可以做到一份函数 , 针对不同的数据进行计算处理。
def calcSum(beg,end):
sum=0
for i in range(beg,end+1):
sum+=i
print(sum)
calcSum(1,100)
calcSum(300,400)
上面的代码中, beg, end 就是函数的形参. 1, 100 / 300, 400 就是函数的实参。
在执行 sum(1, 100) 的时候 , 就相当于 beg = 1, end = 100 , 然后在函数内部就可以针对 1-100 进行运算。在执行 sum(300, 400) 的时候 , 就相当于 beg = 300, end = 400 , 然后在函数内部就可以针对300-400 进行运算。
注意:
- 一个函数可以有一个形参, 也可以有多个形参, 也可以没有形参。
- 一个函数的形参有几个, 那么传递实参的时候也得传几个. 保证个数要匹配。

函数的返回值
def calcSum(beg, end):
sum = 0
for i in range(beg, end+1):
sum += i
return sum
result = calcSum(1, 100)
result = calcSum(300, 400)
上述的这种写法是 "逻辑和用户交互分离". 而在函数参数定义里面的写法函数中, 既包含 了计算逻辑, 又包含了和用户交互(打印到控制台上). 这种写法是不太好的, 如果后续我们需要的是 把计算结果保存到文件中, 或者通过网络发送, 或者展示到图形化界面里, 那么第一种写法的函数, 就难以胜任了. 而第二种写法则专注于做计算逻辑, 不负责和用户交互. 那么就很容易把这个逻辑搭配不同的用户交互代码, 来实现不同的效果。
一个函数可以有多个return语句
判断是否是奇数:
def test(num):
if num % 2 == 0:
return False
else:
return True
result = test(10)
print(result)
def test(num):
if num % 2 == 0:
return False
return True
result = test(10)
print(result)
上述的两个代码逻辑是等价的!
如果输入的一个数%2==0;那么return False;就说明是偶数,如果输入的数是奇数,if的条件判断就不会进行,直接return True。
⭐⭐如果if里面没有return语句就不能这么写!
在Python中可以实现一个函数可以返回多个值!(所以C++、Java都 馋/(ㄒoㄒ)/~~了),在C++,Java中调用一个函数只能返回一个值 /(ㄒoㄒ)/~~
多元赋值
def test():
x = 10
y = 20
return x, y
a, b = test()
a对应x,b对应y;返回部分值。
可以使用_(下斜线)来忽略不想要的值
def test():
x = 10
y = 20
return x, y
_, b = test()
结果:只传来y的20
变量作用域
def test():
x = 10
y = 20
return x, y
a, b = test()
上述中:函数里的x,y和函数外的x,y不是同一组变量!!!它们只是名字相同而已~
就好比:我给我女朋友的备注是“宝贝”,有的人也给他的女朋友备注“宝贝”(咳~~,前提是得有女朋友,女朋友只是是博主的幻想 /(ㄒoㄒ)/~~ )
函数外的变量是全局变量,在整个程序中都有效;函数内的是局部变量,只能在函数内有效。
当然在函数内尝试读取全局变量也是可以的!当函数中尝试访问某个变量知道时候,就会先尝试在局部变量中查找,如果找到,南无就直接访问;如果找不到,就会往上一级作用域中进行查找~
x = 10
def test ():
print(f'x={x}')
test()
global关键字
如果想在函数内部,修改全局变量的值,需要使用global关键字声明
函数执行过程
调用函数才会执行函数体代码 . 不调用则不会执行 .函数体执行结束 ( 或者遇到 return 语句 ), 则回到函数调用位置 , 继续往下执行 .

调试、断点

- 右键, Debug, 可以按照调试模式执行代码. 每次执行到断点, 程序都会暂停下来.
- 使用 Step Into (F7) 功能可以逐行执行代码.
链式调用
把一个函数的返回值 , 作为另一个函数的参数 , 这种操作称为 链式调用。
def test(num):
if num % 2 == 0:
return False
else:
return True
result = test(10)
print(result)
可以简化成
print(test(10))
嵌套调用
- 函数内部还可以调用其他的函数, 这个动作称为 "嵌套调用”
- test 函数内部调用了 print 函数, 这里就属于嵌套调用
def test():
print("执行函数内部代码")
print("执行函数内部代码")
print("执行函数内部代码")
def a():
print("函数 a")
def b():
print("函数 b")
a()
def c():
print("函数 c")
b()
def d():
print("函数 d")
c()
d()
这种也是嵌套。
栈帧:
函数之间的调用关系 , 在 Python 中会使用一个特定的数据结构来表示 , 称为 函数调用栈 . 每次函数调用 , 都会在调用栈里新增一个元素, 称为 栈帧 .
- 在调试器的左下角,就能看到函数之间的“调用栈”~
- 调用栈里面描述了当前这个代码的函数之间的调用关系是啥~
- 每一次这个调用关系就称为“函数的栈帧”,每个函数的局部变量就是在这个栈帧中体现的~
- 每一次栈帧,选中之后,都能看到里面的局部变量,每个函数的局部变量保持在对应的栈帧中~
- 调用函数,则生成对应的栈帧。
- 函数结束,则对应的栈帧消亡(里面的局部变量也就没了)~
函数递归
递归是 嵌套调用 中的一种特殊情况 , 即一个函数嵌套调用自己。

def facotr(n):
if n == 1:
return 1
return n * factor(n-1)
result = facotr(5)
print(result)
注意:
递归的优点
- 递归类似于 "数学归纳法" , 明确初始条件, 和递推公式, 就可以解决一系列的问题.
- 递归代码往往代码量非常少.
递归的缺点
- 递归代码往往难以理解, 很容易超出掌控范围
- 递归代码容易出现栈溢出的情况
- 递归代码往往可以转换成等价的循环代码. 并且通常来说循环版本的代码执行效率要略高于递归版本.
参数默认值
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))
print(add(10, 20, False))
第三个参数是False时候,就不会打印函数内部的那句调试信息。
反之:
注意:

关键字参数:
在调用函数的时候 , 需要给函数指定实参 . 一般默认情况下是按照形参的顺序 , 来依次传递实参的 .但是我们也可以通过 关键字参数 , 来调整这里的传参顺序 , 显式指定当前实参传递给哪个形参 .
def test(x, y):
print(f'x = {x}')
print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)
