菜单

Administrator
发布于 2026-10-16 / 1 阅读
0
0

Python P5:函数——def、调用、参数、return,一次讲透

Python P5:函数——def、调用、参数、return,一次讲透

P3 的 for 循环、P4 的字典,都是"散装代码"——从上往下写一遍,干完就散。真实脚本里,同一段逻辑要在十个地方用:巡检 100 台服务器,总不能把 for 循环复制 100 遍。

函数就是把一段操作打包、起名、以后叫名字就能用。这是 Python 里最重要的组织方式,这篇一次讲透。


一、函数是什么:造一台机器

def double(number):
    return number * 2

一句话:函数 = 封装好的一坨操作,起个名,以后叫名字就能用。

用"造机器"来理解,三个部分:

1. def double(number): —— 造机器,不干活

  • def = 定义(define),告诉 Python:我要造一台机器

  • double = 机器的名字,你自己起,要见名知意

  • (number) = 进料口,叫参数。现在里面什么都没有,是个空位

  • 冒号 + 缩进:老规矩

注意:def 这行只是把机器造好放那,一次都没运行。 屏幕上什么都不会发生。

2. 缩进里的代码 —— 机器内部的加工步骤

    return number * 2

def 那行只给了名字和进料口,干什么活看缩进里的代码。这里的活就是:把传进来的 number 乘以 2。

3. 调用 —— 开机干活

result = double(3)

写出"函数名 + 括号"的那一刻,机器才开机。 double(3) 的意思是:叫 double 干活,原料是 3。

完整的时间顺序:

  1. Python 先算等号右边:double(3)

  2. 开机,3 从进料口 number 塞进去——这一瞬间 number 就是 3

  3. 机器里算 number * 2,得到 6

  4. return 6 把 6 递出来——这一刻,double(3) 整个就变成了 6

  5. 等号右边现在是 6,执行 result = 6

二、return:出货口

return 是机器内部的出货口,它的活有三件:

  1. 算:把后面的表达式算出来。return number * 2,number 是 3 就算出 6

  2. 递:把成品递到机器外面,交给调用的人

  3. 停:递完机器就停——return 后面的代码再也不执行

def check_disk(usage):
    if usage > 90:
        return "危险"
    if usage > 70:
        return "警告"
    return "正常"

check_disk(95):第一个 if 命中,return "危险",直接出货停机,后面看都不看。

为什么不能写 result = return?

新手常问:return 在里面,result 在外面,干嘛不直接 result = return?

因为 return 是机器内部的出货口,只能写在 def 里面。你站在机器外面,够不着它。外面能用的只有函数名:

  • 里面:return 负责往外递

  • 外面:函数名(原料) 负责叫它干活,result = 负责接货

分工清楚,各管一头。

没有 return 的函数

def say_hello():
    print("开机了!")

def say_hello(): 括号里没写参数——这台机器不要原料,调用时 say_hello() 也不用传。

它没有 return,只 print。这种函数干完活不交货,调用它的表达式的值是 None(P2 学过:空值)。print() 本身就是这种——打印完就完,不返回东西。

三、参数:进料口的规矩

位置对应

def add(first, second):
    return first + second

add(2, 3)   # first=2, second=3,按顺序对上

定义时留几个空位,调用时塞几个原料,按顺序一一对应。

原料可以是任何表达式

括号里放任何"能算出值"的东西都行,Python 先算出值再塞进去:

add(2, 3)            # 具体的值
add(total, 3)        # 变量(total 得先有值)
add(2 + 3, 10 - 1)   # 算式,先算出 5 和 9 再传
add(len("abc"), 1)   # 函数调用,先算出 3 再传

跟 f-string 的花括号一个规矩:括号里放表达式,先算出值再办事。

形参 vs 实参(名字别怕)

  • 形参:def 里写的 number、first,是空位的名字,只在机器内部有效

  • 实参:调用时塞的 3、total,是真正的东西

def double(number):   # number 是形参,空位
    return number * 2

n = 5
double(n)             # n 是实参,传的是 5 这个值

里外都叫 number 也没关系——它们是两个世界的人,互不干扰。

四、调用:你早就一直在用

"调用"就是使用函数,写法固定:函数名 + 括号。

  • double(3) → 调用了 double

  • 光写 double 不加括号 → 不算调用,就是个名字

其实 P1 到现在,你一直在调用,只是没叫这个名字:

你写过的

在干嘛

print("hi")

调用 print

input("你叫什么?")

调用 input

log.split()

调用 split 方法

"abc".upper()

调用 upper 方法

len("abc")

调用 len

每个括号都是一次"开机"。方法就是"长在某个东西身上的函数":log.split() = 调用 log 身上的 split。

五、为什么需要函数:三个理由

1. 不复制粘贴

巡检 100 台服务器:

def check_server(name):
    print(f"正在巡检 {name} ...")
    # ... 一堆检查逻辑 ...

for server in ["web1", "web2", "db1"]:
    check_server(server)

逻辑写一遍,调用 100 次。改逻辑只改一处。

2. 起名就是文档

parse_log(log)        # 一看就知道:解析日志
check_disk(usage)     # 检查磁盘
send_alert(message)   # 发送告警

好名字顶半篇注释——这就是为什么变量名、函数名都要见名知意。

3. 分而治之

大任务拆成小函数,每个只干一件事:

def parse_log(log):
    parts = log.split()
    return {"date": parts[0], "time": parts[1], "level": parts[2]}

def is_error(info):
    return info["level"] == "ERROR"

def format_alert(info, raw):
    return f"[{info['time']}] 发现错误:{raw}"

for log in logs:
    info = parse_log(log)
    if is_error(info):
        print(format_alert(info, log))

每个函数三五行,一眼看懂,合起来就是 P3 的日志巡检脚本——这就是"搭积木"式编程。

六、变量名规范(再强调一次)

函数名、变量名统一规矩:

  1. 只能用字母、数字、下划线,不能以数字开头

  2. 不能用关键字(if、for、def、return…)

  3. 区分大小写

  4. 小写 + 下划线,见名知意:parse_log、error_count、server_ip

代码是写给人看的。名字起得好,三个月后回来看还一眼就懂。


小结

知识点

一句话

def

造机器,只定义不运行

调用

函数名 + 括号 = 开机,括号里塞原料

参数

进料口,定义时是空位(形参),调用时传真东西(实参)

return

出货口:算出来、递出去、停机器

无 return

返回 None,比如 print()

原料

任何表达式都行,先算出值再传

方法

长在东西身上的函数,log.split()

P1 到 P5,Python 的地基齐了:数据类型、字符串操作、流程控制、字典、函数。后面就是拿这些积木盖房子——文件读写、网络请求、浏览器自动化,番外篇见。


评论