一、为什么要学函数?
想象你每天早晨要做一杯咖啡:磨豆→加热水→过滤→加奶。如果每次都要手动执行所有步骤,效率极低。而函数就像咖啡机——将固定流程封装,一键即可完成复杂操作。
函数的三大优势:
- 代码复用:一次定义,无限调用
- 逻辑清晰:复杂程序模块化
- 易于维护:修改一处,全局生效
二、函数基础入门
- 定义你的第一个函数
使用 def
关键词 + 函数名称,即可定义函数;而后直接使用函数名称调用函数即可使用函数。
def make_coffee():
print("磨咖啡豆...")
print("注入热水...")
print("完成过滤!")
print("☕ 您的咖啡好了")
# 调用函数(注意要加括号!)
make_coffee()
- 带参数的函数
当函数需要传入参数时,直接在定义函数的函数名后添加参数即可,使用 =
给参数默认值。
def make_coffee(coffee_type, sugar=1):
"""
:param coffee_type: 咖啡种类
:param sugar: 糖量(默认1勺)
"""
print(f"正在制作{sugar}勺糖的{coffee_type}咖啡...")
make_coffee("拿铁") # 使用默认糖量
make_coffee("摩卡", sugar=3) # 指定糖量
- 函数的返回值
使用 return
关键词,可以将函数的处理结果进行返回。
def calculate_bmi(weight, height):
bmi = weight / (height ** 2)
return round(bmi, 1) # 返回保留一位小数
result = calculate_bmi(70, 1.75)
print(f"您的BMI指数是:{result}")
# 没有return时默认返回None
def test():
print("这个函数返回None")
print(test()) # 输出None
三、函数进阶技巧
1. 类型提示
Python3.5+支持定义函数时,强制函数入参和返参类型。
def greet(name: str) -> str:
return f"你好,{name}!"
2. 多返回值
Python还支持多返回值,定义函数时,使用 ,
分割多个返回值。在调用函数时,使用相同数量的变量进行赋值即可。
def analyze_numbers(numbers):
return min(numbers), max(numbers), sum(numbers)/len(numbers)
min_val, max_val, avg = analyze_numbers([5,2,9,7])
3. Lambda表达式
Python还支持使用 lambda
关键词简化函数定义和调用。
# lambda 函数入参 : 函数处理和返参
square = lambda x: x**2
print(square(5)) # 输出25
4. 位置参数
准确描述:位置参数是指可以通过位置顺序传递的参数,但也可以通过参数名传递。
特点:
- 默认情况下,Python函数的参数既可以通过位置传递,也可以通过关键字传递
- 参数顺序决定了调用时的匹配方式
代码示例:
def greet(name, greeting):
print(f"{greeting}, {name}!")
# 两种调用方式都有效
greet("Alice", "Hello") # 通过位置
greet(greeting="Hi", name="Bob") # 通过关键字
4.1 强制位置参数(Positional-only parameters)
Python 3.8+ 引入了强制位置参数,使用 /
符号表示。
特点:
- 只能通过位置传递,不能使用关键字
- 在参数列表中使用/表示前面的参数必须作为位置参数
- 提高代码可读性和性能
代码示例:
def pow(x, y, /):
return x ** y
pow(2, 3) # 正确
pow(x=2, y=3) # 报错: TypeError
4.2 命名关键字参数 (Keyword-only arguments)
使用 *
符号表示后面的参数必须作为关键字参数传递。
特点:
- 必须通过参数名明确指定
- 在参数列表中使用*表示后面的参数必须用关键字传递
- 提高代码可读性,避免参数混淆
代码示例:
def person_info(name, *, age, job):
print(f"{name}, {age}, {job}")
person_info("Alice", age=25, job="Engineer") # 正确
person_info("Bob", 30, "Teacher") # 报错: TypeError
5. 可变参数 (Variable arguments)
*args
- 可变位置参数
def sum_numbers(*args):
return sum(args)
sum_numbers(1, 2, 3) # 输出6
**kwargs
- 可变关键字参数
def print_info(**kwargs):
for k, v in kwargs.items():
print(f"{k}: {v}")
print_info(name="Alice", age=25)
6. 高阶函数 (Higher-order Functions)
高阶函数是指能够接收其他函数作为参数,或者返回函数作为结果的函数。
特点:
- 函数可以作为参数传递
- 函数可以作为返回值
- 增强了代码的抽象能力和灵活性
示例:
6.1 map()
函数
对可迭代对象的每个元素应用函数
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, numbers))
print(squared) # 输出: [1, 4, 9, 16]
6.2 filter()
函数
过滤符合条件的元素
numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # 输出: [2, 4, 6]
6.3 sorted()
函数
自定义排序
words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words) # 输出: ['date', 'apple', 'banana', 'cherry']
6.4 自定义高阶函数
def apply_operation(func, x, y):
return func(x, y)
result = apply_operation(lambda a, b: a * b, 5, 3)
print(result) # 输出: 15
7. 偏函数 (Partial Functions)
偏函数是通过固定原函数的部分参数,创建一个新函数的技术。
特点:
- 简化函数调用
- 固定某些参数值
- 使用
functools.partial
创建
示例:
- 基本使用
from functools import partial
def power(base, exponent):
return base ** exponent
# 创建平方函数
square = partial(power, exponent=2)
print(square(5)) # 输出: 25
# 创建立方函数
cube = partial(power, exponent=3)
print(cube(3)) # 输出: 27
- 固定多个参数
def greet(greeting, name, punctuation):
return f"{greeting}, {name}{punctuation}"
say_hello = partial(greet, "Hello", punctuation="!")
print(say_hello("Alice")) # 输出: Hello, Alice!
- 与map结合使用
from functools import partial
numbers = [1, 2, 3, 4]
add_five = partial(map, lambda x: x + 5)
result = list(add_five(numbers))
print(result) # 输出: [6, 7, 8, 9]
- 实际应用场景
# 处理文件时固定编码方式
open_utf8 = partial(open, encoding='utf-8')
# 代替以下写法
# with open('file.txt', 'r', encoding='utf-8') as f:
with open_utf8('file.txt', 'r') as f:
content = f.read()
四、最佳实践建议
- 命名规范:使用动词+名词组合,如
calculate_total
- 函数长度:单个函数不超过30行
- 文档字符串:用三引号说明函数功能
- 参数设计:超过3个参数建议使用字典
实战:用函数发送邮件(以QQ邮箱为例)
准备步骤
-
登录QQ邮箱 → 设置 → 账户
-
开启POP3/SMTP服务
-
生成16位授权码(非登录密码!)
完整代码实现
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
def send_email(to_email, subject, content):
"""
发送邮件的万能函数
:param to_email: 收件人邮箱
:param subject: 邮件主题
:param content: 正文内容(支持HTML)
"""
# 1. 构建邮件
msg = MIMEText(content, "html", "utf-8")
msg["From"] = formataddr(["Python小助手", "your_email@qq.com"]) # 发件人
msg["To"] = to_email # 收件人
msg["Subject"] = subject # 主题
# 2. 连接服务器
server = smtplib.SMTP_SSL("smtp.qq.com", 465) # QQ邮箱SSL端口
server.login("your_email@qq.com", "你的授权码") # 邮箱+授权码
# 3. 发送邮件
server.sendmail("your_email@qq.com", to_email, msg.as_string())
server.quit()
print("📮 邮件发送成功!")
# 使用示例
send_email(
to_email = "friend@example.com",
subject = "来自Python的问候",
content = "<h2 style='color:blue'>你好!</h2>这是用Python发送的邮件~"
)
关键点解析
MIMEText
支持HTML格式,可以发送带样式的邮件- SMTP_SSL确保加密传输
- 授权码需要妥善保管,不要写入公开代码
常见问题解决
-
为什么收不到邮件?
-
检查垃圾邮件箱
-
确认授权码正确
-
确保开启SMTP服务
-
函数报错怎么办?
-
使用try-except捕获异常:
try: send_email(...) except Exception as e: print(f"发送失败: {str(e)}")
通过本文,你已经掌握了Python函数的核心用法,并能实现自动发送邮件的实用功能。函数就像编程世界的乐高积木,合理组合就能构建强大系统。现在,尝试用函数改造你的代码吧!
练习建议:编写一个系统监控函数,当CPU使用率超过90%时自动发送告警邮件(可使用psutil库获取系统信息)