?🌈个人主页:?会编程的果子君
?💫个人格言:“成为自己未来的主人~”
?
目录
观察下面的代码
?
def getpoint():
x=10
y=20
return x,y
x,y=getpoint()
在这个代码中,函数内部存在x,y,函数外部也有x,y
但是这两组x,y不是相同的变量,而只是恰好有一样的名字
变量只能在所在的函数内部生效
在函数getpoint()内部定义的x,y只是在函数内部生效,一旦出了函数的范围,这两个变量就不生效了。
def getpoint():
x=10
y=20
return x,y
print(x,y)
在不同的作用域中,允许存在同名的变量
?
x=10
def test():
x=10
print(f'函数内部={x}')
test()
print(f'函数外部={x}')
?
主意:
如果函数内部尝试访问的变量在局部不存在,就会尝试去全局作用域中查找
x=10
def test():
print(f'x={x}')
test()
?
如果想在函数内部,修改全局变量的值,需要使用global关键字声明
?
def test():
global x
x=10
print(f'函数内部 x = {x}')
test()
print(f'函数外部 x = {x}')
?
如果此处没有global。则函数内部的x=10,就会被视为是创建一个局部变量x?,这样就和全局变量x不相关了。
if/while/for等语句块不会影响到变量作用域
换而言之,在if/while/for中定义的变量,在语句外面也可以正常使用
for i in range(1,11):
print(f'函数内部 i ={i}')
print(f'函数外部 i ={i}')
def test():
print('执行函数内部代码')
print('执行函数内部代码')
print('执行函数内部代码')
print("1111")
test()
print("2222")
test()
?
?
def isodd(num):
if num % 2 ==0:
return False
else:
return True
result = isodd(10)
print(result)
实际上也可以简化写作
?
print(isodd(10))
把一个函数的返回值,作为另一个函数的参数,这种操作成为链式调用
这是一种比较常见的写法
函数内部还可以调用其他的函数,这个动作称为“嵌套调用”
?
def test():
print('执行函数内部代码')
print('执行函数内部代码')
print('执行函数内部代码')
test函数内部调用了print函数,这就属于嵌套调用
一个函数可以嵌套调用任意多个函数
函数嵌套的过程是非常灵活的
?
def a():
print('a')
def b():
print('b')
a()
def c():
print('c')
b()
def d():
print('d')
c()
d()
?
如果把代码稍微调整,打印结果则可能发生很大变化
?
def b():
a()
print('b')
def c():
b()
print('c')
def d():
c()
print('d')
d()
注意体会上述代码的执行顺序,可以通过画图的方式来理解
函数之间的调用关系,在Python中会使用一个特定的数据结构来表示,称为 “函数调用栈”,每次函数调用,?都会在调用栈里新增一个元素,称为 栈帧
可以通过PyCharm调试器看到函数调用栈和栈帧
在调试状态下,pycharm左下角一般就会显示出函数调用栈
递归是嵌套调用中的一种特殊情况,即一个函数嵌套调用自己
代码示例:递归计算5!
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的时候,递归就结束了
每次递归的时候,要保证函数的实参是逐渐逼近结束条件的
如果上述条件不能满足,就会出现无限递归,这是一种典型的代码错误
?
def factor(n):
return n * factor(n-1)
result=factor(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))
此处debug=False即为参数默认值,当我们不指定第三个参数的时候,默认debug的取值即为False
带有默认值的参数需要放到没有默认值的参数的后面
?
def add(x,debug=False,y):
if debug:
print(f'调试信息: x={x},y={y}')
return x+y
print(add(10,20))
print(add(10,20,True))
?
在调用函数的时候,需要给函数指定实参,一般默认情况下是按照形参的顺序,来依次传递实参的,但我们也可以通过关键字参数,来调整这里的传参顺序,显示指定当前实参给哪个形参。
?
def test(x,y):
print(f'x={x}')
print(f'y={y}')
test(x=10,y=20)
test(x=20,y=10)
?
形如上述test(x=10,y=20)这样的操作,即为关键字参数
函数是编程语言中的一个核心语法机制,Python中的函数和大部分编程语言的函数功能都是非常重要的
我们当下最重要的就是三个点:
函数的定义
函数的调用
函数的参数传递
?