不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。
python系列之函数基础
python系列前期章节
- python系列之注释与变量
- python系列之输入输出语句与数据类型
- python系列之运算符
- python系列之控制流程语句
- python系列之字符串
- python系列之列表
- python系列之元组
- python系列之字典
- python系列之集合
一、前言
在前面的篇幅中已经介绍了python的很多语法,其中最多的是数据类型,每一门编程语言都有其独特的数据类型,python也一样,然后也学习了控制流程语句、运算符等在编程中重要的角色。而接下来将会进入一个新的领域——函数,函数在一些编程语言中是叫方法;在python中,函数是一个重要的角色,在后续的开发中,会经常打交道。那么废话不多说,咱们进入新的篇章吧~
一、为什么需要函数?先看一个真实场景
场景:你正在开发一个电商系统,需要频繁计算不同商品的折扣价格。
小白写法:每次手动重复计算
price1 = 100
discount1 = 0.8
final_price1 = price1 * disc_ount1 # 这里有拼写错误!
price2 = 200
discount2 = 0.7
final_price2 = price2 * discount2 # 重复劳动,容易出错
函数写法:
def calculate_price(price, discount):
return price * discount
print(calculate_price(100, 0.8)) # 输出80.0
print(calculate_price(200, 0.7)) # 输出140.0
通过上面的栗子我们知道:函数就是代码复用+错误隔离的利器!
二、函数基础:解剖一只“代码盒子”
1. 函数定义三要素
def 函数名(参数):
"""文档字符串(可选)"""
操作代码
return 返回值
2. 参数传递:位置 vs 关键字
场景:咖啡店点单系统
def make_coffee(size, coffee_type="拿铁", sugar=True):
print(f"制作一杯{size}的{coffee_type}{',加糖' if sugar else ''}")
# 位置参数,一一对应定义从形参
make_coffee("中杯", "美式") # 制作一杯中杯的美式,加糖
# 关键字参数
make_coffee(coffee_type="卡布奇诺", size="大杯") # 制作一杯大杯的卡布奇诺,加糖
# 默认参数
make_coffee("小杯") # 制作一杯小杯的拿铁,加糖
3. 返回值:不止能返回一个值
场景:解析用户输入的RGB颜色值
def parse_rgb(color_str):
r = int(color_str[1:3], 16)
g = int(color_str[3:5], 16)
b = int(color_str[5:7], 16)
return r, g, b # 返回元组
# 解包
red, green, blue = parse_rgb("#FF00FF")
print(f"红色分量:{red}") # 输出255
三、函数与数据类型的实战演练
案例1:字符串处理 - 用户注册验证
def validate_username(username):
if len(username) < 4:
return False, "用户名至少4个字符"
if not username.isalnum():
return False, "只能包含字母和数字"
return True, "验证通过"
result, msg = validate_username("user123")
print(msg) # 验证通过
案例2:列表操作 - 购物车管理
def add_to_cart(cart, item, quantity=1):
for product in cart:
if product["name"] == item:
product["quantity"] += quantity
return cart
cart.append({"name": item, "quantity": quantity})
return cart
my_cart = []
my_cart = add_to_cart(my_cart, "苹果")
my_cart = add_to_cart(my_cart, "香蕉", 3)
print(my_cart) # [{'name': '苹果', 'quantity': 1}, {'name': '香蕉', 'quantity': 3}]
案例3:字典处理 - 用户信息统计
def count_user_ages(users):
age_count = {}
for user in users:
age = user.get("age")
if age:
age_count[age] = age_count.get(age, 0) + 1
return age_count
users = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 25}
]
print(count_user_ages(users)) # {25: 2, 30: 1}
四、函数进阶技巧:让代码更优雅
1. 可变参数:处理不定长数据
# 单星号的(*):用于将所有位置参数以 元组 的形式传递给函数
# 双星号(**)用于将所有关键字参数以 字典 的形式传递给函数。
def create_report(title, *sections, **footer):
print(f"# {title}")
for i, section in enumerate(sections, 1):
print(f"{i}. {section}")
print("\nFooter:")
for key, value in footer.items():
print(f"{key}: {value}")
create_report("销售报告",
"季度增长15%",
"新产品表现优异",
company="XX科技",
date="2024-03")
2. 列表推导式+函数的组合技
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
return True
primes = [x for x in range(100) if is_prime(x)]
print(primes) # 输出100以内的质数列表
五、常见问题QA(小白最常踩的坑)
Q1:函数内修改列表会影响外部变量?
def add_suffix(items):
items.append("_processed") # 直接修改原列表!
data = ["a", "b"]
add_suffix(data)
print(data) # ['a', 'b', '_processed']
# 正确做法:创建新列表
def safe_add_suffix(items):
return [item + "_safe" for item in items]
Q2:默认参数为什么不能用可变类型?
# 危险写法!
def add_item(item, lst=[]):
lst.append(item)
return lst
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] 默认列表被重复使用!
# 正确写法
def safe_add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
Q3:如何同时返回多个结果?
def analyze_text(text):
words = text.split()
char_count = len(text)
# 字典、列表亦可
return {
"word_count": len(words),
"avg_length": char_count/len(words),
"longest_word": max(words, key=len)
}
result = analyze_text("Python让编程更简单")
print(result["avg_length"]) # 4.0
六、综合实战:开发一个迷你数据分析工具
def data_analyzer(data):
# 类型自动判断处理
if isinstance(data, list):
return {
"类型": "列表",
"长度": len(data),
"数值型元素": sum(1 for x in data if isinstance(x, (int, float))),
"去重后长度": len(set(data))
}
elif isinstance(data, dict):
return {
"类型": "字典",
"键数量": len(data),
"包含字符串的键": [k for k in data if isinstance(k, str)]
}
else:
return {"类型": str(type(data)), "原始值": data}
print(data_analyzer([1,2,2,3,"a"]))
# {'类型': '列表', '长度': 5, '数值型元素': 3, '去重后长度': 4}
print(data_analyzer({"name": "Bob", 123: "test"}))
# {'类型': '字典', '键数量': 2, '包含字符串的键': ['name']}
七、学习路线图:函数相关技能树
基础函数
├─ 参数传递
│ ├─ 位置参数
│ ├─ 关键字参数
│ └─ 默认参数
└─ 返回值处理
├─ 单返回值
└─ 多返回值解包
高级函数(下一章分晓)
├─ lambda表达式
├─ 闭包
├─ 装饰器
└─ 生成器