Python基础语法学习:函数

一、什么是函数

Python 中的函数,可以理解成一段可以重复使用的代码。

例如下面这些代码虽然计算的范围不同,但是整体逻辑其实完全一样:

python 复制代码
sum = 0

for i in range(1, 101):
    sum += i

print(sum)

如果这种代码在程序里出现很多次,最直接的方法就是复制粘贴,但这种方式并不利于维护。假如以后计算逻辑发生变化,就可能需要修改很多份代码。

更合理的办法是把重复的部分提取出来:

python 复制代码
def calcSum(beg, end):
    sum = 0

    for i in range(beg, end + 1):
        sum += i

    return sum

之后直接调用:

python 复制代码
print(calcSum(1, 100))
print(calcSum(300, 400))
print(calcSum(1, 1000))

这样重复代码就被消掉了。


二、函数的定义和调用

Python 使用 def 定义函数:

python 复制代码
def 函数名(形参列表):
    函数体
    return 返回值

比如:

python 复制代码
def hello():
    print("hello")

注意一个很重要的地方:

定义函数并不会执行函数内部的代码。

只有真正调用函数时,函数体才会执行。

python 复制代码
def hello():
    print("hello")

hello()

调用一次,执行一次;调用两次,就执行两次。

而且函数必须先定义,再使用。如果在定义之前就调用,程序会出问题。


三、函数参数

函数可以通过参数接收数据。

定义函数时写的是形参 ,调用函数时传进去的是实参。

例如:

python 复制代码
def calcSum(beg, end):
    sum = 0

    for i in range(beg, end + 1):
        sum += i

    return sum

这里:

text 复制代码
beg、end

就是形参。

而:

python 复制代码
calcSum(1, 100)

里面的:

text 复制代码
1、100

就是实参。

调用:

python 复制代码
calcSum(1, 100)

可以理解成函数内部接收到:

text 复制代码
beg = 1
end = 100

再进行计算。

一个函数可以有多个参数,也可以没有参数。

例如:

python 复制代码
def test():
    print("hello")

也可以:

python 复制代码
def test(a, b, c):
    print(a, b, c)

调用时,参数数量必须匹配。


四、Python函数参数不需要写类型

Python 是动态类型语言,所以定义函数的时候,不需要像 C++ 那样写参数类型。

比如:

python 复制代码
def test(a):
    print(a)

这个函数可以传:

python 复制代码
test(10)
test('hello')
test(True)

不需要额外指定:

text 复制代码
int
string
bool

等类型。


五、函数返回值

函数参数可以理解成函数的输入,而 return 返回的结果可以理解成函数的输出。

比如:

python 复制代码
def calcSum(beg, end):
    sum = 0

    for i in range(beg, end + 1):
        sum += i

    return sum

然后:

python 复制代码
result = calcSum(1, 100)
print(result)

这里函数只负责计算,至于结果怎么处理,由调用者决定。

我觉得这种写法非常重要。

函数里面最好主要负责自己的逻辑,不要把计算和用户交互全部混在一起。

比如不太推荐:

python 复制代码
def calcSum(beg, end):
    ...
    print(sum)

更推荐:

python 复制代码
def calcSum(beg, end):
    ...
    return sum

这样以后结果是保存到文件,还是打印到控制台,甚至用于其他计算,都可以由外部决定。


六、return会立即结束函数

一个函数可以有多个 return。

例如判断奇数:

python 复制代码
def isOdd(num):
    if num % 2 == 0:
        return False

    return True

如果 num 是偶数,执行:

python 复制代码
return False

函数就直接结束,不会继续往后执行。

所以看到 return 的时候,可以直接想到:

text 复制代码
结束当前函数
返回结果
回到调用的位置

七、函数可以返回多个值

Python 支持:

python 复制代码
def getPoint():
    x = 10
    y = 20
    return x, y

调用:

python 复制代码
a, b = getPoint()

这里实际上可以一次得到两个结果。

如果某个返回值暂时不需要,可以使用 _ 忽略:

python 复制代码
_, b = getPoint()

八、变量作用域

函数里面的变量,并不一定和外面的同名变量是同一个。

例如:

python 复制代码
x = 20

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

test()
print(x)

输出时,函数内部和函数外部的 x 是两个不同的变量。

函数内部的变量叫做局部变量 ,函数外部的变量叫做全局变量。

如果函数内部没有找到对应的局部变量,就会继续到全局作用域中寻找。

如果确实需要在函数内部修改全局变量,可以使用:

python 复制代码
global x

例如:

python 复制代码
x = 20

def test():
    global x
    x = 10

test()

print(x)

还有一个容易和 C++ 思维混淆的地方:

if、while、for 这些代码块不会产生新的变量作用域。

也就是说,在循环或者条件语句中创建的变量,出了这些代码块之后仍然可以使用。


九、函数调用过程

调用函数时,程序会进入函数内部执行。

函数执行结束,或者遇到 return,就会回到函数调用的位置继续执行。

例如:

python 复制代码
def test():
    print("函数内部代码")

print("1111")
test()
print("2222")
test()
print("3333")

执行顺序就是:

text 复制代码
1111
函数内部代码
2222
函数内部代码
3333

调试的时候,还可以在 PyCharm 中下断点,通过 Debug 和 Step Into 一步一步观察函数的执行过程。


十、链式调用和嵌套调用

如果把一个函数的返回值直接作为另一个函数的参数,这种操作叫做链式调用。

例如:

python 复制代码
print(isOdd(10))

就比:

python 复制代码
result = isOdd(10)
print(result)

更简洁。

函数内部还可以调用其他函数,这叫做嵌套调用。

比如:

python 复制代码
def a():
    print("函数 a")

def b():
    a()
    print("函数 b")

b()

执行 b() 的时候,会先进入 b,然后调用 a,a 执行完以后再回到 b。


十一、函数调用栈

函数之间互相调用的时候,Python 会使用一个叫做函数调用栈的数据结构来记录当前调用关系。

每调用一次函数,调用栈中就会增加一个栈帧。

每个函数自己的局部变量,都保存在对应的栈帧中。


十二、递归

递归其实就是一种特殊的嵌套调用:

函数调用自己。

例如计算阶乘:

python 复制代码
def factor(n):
    if n == 1:
        return 1

    return n * factor(n - 1)

调用:

python 复制代码
print(factor(5))

执行过程大致是:

text 复制代码
factor(5)
    ↓
5 * factor(4)
        ↓
        4 * factor(3)
                ↓
                3 * factor(2)
                        ↓
                        2 * factor(1)

到了:

python 复制代码
n == 1

满足结束条件,开始一层层返回。

递归最重要的一点就是:

必须有结束条件,而且每次递归都要逐渐接近这个条件。

否则就会出现无限递归。

递归的优点是代码往往比较短,而且很像数学中的递推过程。

但是它也有缺点:

text 复制代码
代码不容易理解
容易出现无限递归
可能导致栈溢出
有些问题改成循环后效率更高

所以实际写代码时,递归不能无脑使用。


十三、参数默认值

Python 可以给函数参数设置默认值。

例如:

python 复制代码
def add(x, y, debug=False):
    if debug:
        print(f'调试信息: x={x}, y={y}')

    return x + y

这样:

python 复制代码
add(10, 20)

不传第三个参数时:

text 复制代码
debug = False

也可以:

python 复制代码
add(10, 20, True)

需要注意:

有默认值的参数要放在没有默认值的参数后面。


十四、关键字参数

正常情况下,传参是按照参数顺序来的:

python 复制代码
def test(x, y):
    print(x, y)

test(10, 20)

也可以直接指定参数名称:

python 复制代码
test(x=10, y=20)
test(y=100, x=200)

这种方式叫做关键字参数。


十五、总结

函数是 Python 中非常核心的一部分。

现在最需要掌握的就是:

text 复制代码
函数定义
函数调用
函数参数
返回值
变量作用域
递归
默认参数
关键字参数

以后写稍微复杂一点的程序,基本不可能一直把所有代码堆在一起。

把重复逻辑封装成函数,不仅代码更短,也更方便后续修改和复用。

相关推荐
玖石书36 分钟前
linux 安装uv(python虚拟环境管理)
linux·python·uv
91刘仁德36 分钟前
HTTPS 加密原理与 CA 数字证书:从对称加密到完整通信流程
网络·笔记·网络协议·http·https
言乐640 分钟前
Python体现逻辑回归和决策树的区别
开发语言·python·算法·决策树·逻辑回归
LOVE️YOU1 小时前
Python 类与对象的核心逻辑:从 self、cls 到点号、括号与链式调用
开发语言·python
顶点多余1 小时前
C/C++常见面试题
开发语言·c++
HugoStudio_SWAN1 小时前
洛谷 B4575 [GESP202609 二级] 直角三角形——临场定义理解与边界质疑
c++·学习·程序人生·算法
(Charon)1 小时前
【C++面试】右值引用与移动语义:std::move到底做了什么
开发语言·c++
TheITSea1 小时前
JavaScript Web APIs
开发语言·前端·javascript
空心木偶☜1 小时前
A2A2A(多智能体协作)
开发语言·python·ai·ai编程