Python基础知识“入坑“--- 五、函数(二)


书接上回,我们继续来学习有关函数的内容。

五、变量作用域

def test():
    x = 10
    y = 20
    return x, y

x, y = test()
print(x)
print(y)

在上面这段代码中,我们定义了一个test函数,在函数中有两个变量x和y,在函数外我们使用两个变量来接收函数的返回值,变量名也叫x和y。在这里,函数内部的x和y,和函数外部的x和y,并不是相同的,只是恰好重名而已。
这段代码之所以能正常运行,是因为变量具有作用域。在函数内部定义的变量只在函数内部有效,函数调用结束之后,变量也会被销毁。


def test():
    x = 10
    y = 20
    return x, y

test()
print(x)
print(y)

在这段代码中,虽然我们在函数外调用了test函数,但是函数的返回值并没有在函数外部被接收;也就是说,函数外部并没有名为x的变量,此时我们尝试打印变量x,程序就会抛出异常。(如下图)
在这里插入图片描述


在不同的作用域中,允许存在重名的变量:

def test():
    x = 10
    y = 20
    return x, y

x, y = test()
print(x)
print(y)

依旧是上面这段代码,为了验证函数内部的x和y,与函数外部x和y,不是相同的,我们对代码进行处理,更直观的观察一下:

def test():
    x = 10
    y = 20
    print(f'函数内部x={x}, y={y}')
    return x, y

x, y = test()
print(f'函数外部x={x}, y={y}')

运行上面这段代码,就可以在控制台上清楚的观察到打印的x和y究竟是函数内部的还是函数外部的。

在这里插入图片描述

在函数内部的变量称之为局部变量,不在函数内部的变量称之为全局变量。


我们来看一段代码:

def test():
    print(f'x = {x}')

x = 20
test()

在函数内部我们并没有定义x的值,而当我们调用函数时,函数能打印出全局变量x的值,这是因为:如果函数内部尝试访问的变量在局部作用域中不存在,那么就会尝试在全局作用域中寻找。


如果全局变量和局部变量同名,那么在函数内部会使用哪个变量呢?代码如下:

x = 10
def test():
    x = 20
    print(x)

test()

先在函数外部定义一个全局变量x,再在函数内部定义一个局部变量x,两个变量的值不同;运行上面这段代码,控制台输出的结果为 “20” 。由此可得出:在函数内部,当全局变量和局部变量同名时,局部变量优先。


如果想在函数内部,修改全局变量的值,有没有办法呢?

可以在函数内部使用 “global” 关键字声明要修改的变量:

x = 10
def test():
    global x
    x = 20
    print(f'函数内部x = {x}')

test()
print(f'函数外部x = {x}')

在这段代码中,我们先在函数外部定义了一个全局变量x,在函数内部通过 “global” 关键字使用了全局变量x,再将全局变量x的值修改为 “20”。

正是因为 “global” 关键字,在函数内部的 “x = 20” 这条语句 是在对全局变量x进行赋值操作,而不是在函数内部创建一个名为x的局部变量。


在变量作用域这一知识点这里,我们还要特别注意:在Python中,if / while / for 等语句不会影响变量的作用域;换而言之,在 if / while / for 中定义的变量,在语句外也可以正常使用。

六、函数执行过程

在使用函数时,只有调用函数才会执行函数体内部的代码;当函数体执行结束或者遇到return语句,则会回到函数调用位置,继续往下执行。 我们通过代码来具体理解一下函数的执行过程:

def test():
    print("test")
    print("test2")

print('111')
test()
print('222')
test()

运行结果为:
在这里插入图片描述
在这里插入图片描述

七、链式调用

我们来看一段之前编写过的代码:

# 判断奇数
def is_odd(n):
    if n % 2 != 0:
        return True
    else:
        return False

result = is_odd(5)
print(result)

这段代码中,使用了result来接收函数调用后的返回值,再打印result。

最后两条语句其实可以合并为一条语句:

# 判断奇数
def is_odd(n):
    if n % 2 != 0:
        return True
    else:
        return False

print(is_odd(5))

像这样,将一个函数的返回值直接作为另一个函数的参数,这种操作就称为链式调用。 这也是一种很常见的写法。

八、嵌套调用

函数内部调用其他函数,就称为嵌套调用。

最简单的嵌套调用其实我们已经使用过了:

def test():
    print("test")
    print("test2")

在test函数中调用print函数。


我们再来看一段逻辑较为复杂的代码:

def a():
    print('a')

def b():
    print('b')
    a()

def c():
    print('c')
    b()

def d():
    print('d')
    c()

d()

运行结果为:
在这里插入图片描述
函数的具体执行过程为:
在这里插入图片描述

函数之间的调用关系,在Python中可以使用一个特定的数据结构来表示,称为函数调用栈。 每次函数调用,都会在调用栈里新增一个元素,称为栈帧。 每个函数的局部变量,都包含在自己的栈帧中。

九、函数递归

函数递归是函数嵌套调用的一种特殊的情况,即自己调用自己。递归可以分成两个部分来看:递推和回归。

举个栗子:用函数递归的方式计算5的阶乘:

def test(n):
    if n == 1:
        return 1
    return n * test(n - 1)

print(test(5))

解题思路:
在这里插入图片描述

具体执行过程为:

在这里插入图片描述
在使用递归函数的时候要注意:

1.务必存在递归结束条件。(在上面这个例子中,"if n == 1: " 就是递归结束条件。)
2.每次递归,函数的实参都应逐步趋近于函数结束条件。

若上述条件有一项没满足,就会出现无限递归的情况,这是一种典型的错误!程序也会抛出异常。

十、参数默认值

在Python中,可以给函数的形参指定默认值。带有默认值的参数,在调用的时候可以不传参。
举个栗子:计算两个数的和:

def add(x, y, debug = False):
    if debug:
        print(f'观察传递的参数的值:x = {x}, y = {y}')
    return x + y

print(add(1, 2, True))
print('--------------------------')
print(add(1, 2))

运算结果为:
在这里插入图片描述

这就是一个带有参数默认值的函数,“debug = False” 即为参数默认值,当我们不指定第三个参数的时候,程序就会默认debug的值为False。

为了确保没有默认值的参数可以正常传递,带有默认值的参数需要放到没有默认值的参数的后面。

举个错误例子:

def add(x, debug = False, y):
    if debug:
        print(f'观察传递的参数的值:x = {x}, y = {y}')
    return x + y

print(add(1, 2))

运行这段代码,程序就会报错:
在这里插入图片描述

十一、关键字参数

在调用函数时,需要给函数传递实参,一般情况下,默认都是按照形参的顺序依次传递实参。但是,也可以通过关键字参数 指定实参应该传递给哪个形参:

def test(x, y):
    print(f'x = {x}')
    print(f'y = {y}')

test(x = 10, y = 20)
test(y = 100, x = 200)

形如 “test(x = 10, y = 20)” 这种操作,即为关键字参数。

运行结果为:
在这里插入图片描述

在PyCharm中编写这段代码时,使用关键字参数,参数会变为红色(如下图),这并非错误,不必担心。
在这里插入图片描述

十二、函数小结

函数在编程语言中占据着必不可少的地位,在后续的学习中,我们也会广泛使用到函数。需多加理解、练习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值