智泊Python--Day8

智泊Python–Day8

  Day8 进入函数进阶。函数是 Python 里最核心的封装单元——把重复逻辑包成名字,随时调用。这一天从函数的基本定义、参数、返回值讲起,到练习(闰年、月天数、季节、质数),再到函数嵌套与「函数名即变量」、匿名函数 lambda 与 map/filter 高阶函数、回调函数,最后用回文 / 最值 / 水仙花数四道作业收尾。建议重点吃透参数顺序(位置 → *args → 默认 → 关键字 → **kwargs)和「函数名本质是个变量」这两点,它们是后面装饰器、闭包的地基。

 

1.函数入门

  函数用 def 名字(形参): 定义,调用时给实参。参数按形态分四类:

  • 必需位置参数:必须传实参,不能用默认值
  • 默认参数:没传就用默认值(定义时写在后面)
  • 关键字参数:调用时按 名=值 传,通常和默认参数配合
  • 不定长参数:*args 收多余位置参数(元组)、**kwargs 收多余关键字参数(字典)

形参的定义顺序是铁律:位置参数 → *args → 默认参数 → 关键字参数 → **kwargs;实参传递时位置参数必须写在关键字参数前面。函数没有 return 默认返回 None,return 会立刻结束函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    函数的作用,本质上是对一些重复性的工作进行封装,方便后续的调用
项目 》 文件夹(包) 》 文件(模块) 》 类 》 函数 》 代码

# 函数的定义
def fn():
print('我是函数')

# 函数的调用
# fn()

# 函数的参数
# 形参 : 形式参数 比如 a, b
# 实参 : 实际参数 比如 1, 2
def sum1(a, b):
print(f'a:{a} , b:{b}')
# 返回a + b
return a + b

# 调用函数时,可以接收返回值
result = sum1(1, 2)
print(result)

# 细分参数种类
# 1.必需的位置参数 ,必须传递实参,不能使用默认值
def sum2(a, b):
print(f'a:{a} , b:{b}')
return a + b
sum2(1, 2)

# 2.默认参数,如果调用函数时,没有传递实参,会使用默认值
def sum3(a, b=10):
print(f'a:{a} , b:{b}')
return a + b
sum3(1)

# 3.关键字参数 一般与默认参数结合,可以使用关键字参数传递实参
def sum4(a, b, c=10):
print(f'a:{a} , b:{b} , c:{c}')
return a + b + c
sum4(1, 2, c=3)

# 注:关键字参数必须在位置参数后面,传值时,也必须优先进行位置参数的传值

# 不定长参数
# *args : 可以接收任意数量的位置参数,返回的是一个元组
# **kwargs : 可以接收任意数量的关键字参数,返回的是一个字典
def sum5(*args, **kwargs):
print(args) # (1, 2, 3, 4)
print(kwargs) # {'e': 5, 'f': 6}
return sum(args)
sum5(1, 2, 3, 4, e=5, f=6)

# 函数的参数顺序
# 形参顺序: 位置参数, *args, 默认参数, 关键字参数, **kwargs
# 实参顺序: 位置参数, 关键字参数
def fn(a, b, *args, d=7, e=8, **kwargs):
print(a, b, args, d, e, kwargs)
fn(1,2) # 1 2 () 7 8 {}
fn(1,2,3,4,d=77,e=88,f=99,g=100) # 1 2 (3, 4) 77 88 {'f': 99, 'g': 100}

# 通用参数
def fn2(*args, **kwargs):
print(args, kwargs)

fn2(1,2,3,4,e=5,f=6)

# 返回值: return
# 如果函数没有 return 语句,默认返回 None
# return会立刻结束函数,并返回值
def sum6(a, b):
print(f'a:{a} , b:{b}')
return a + b
sum6(1, 2)

 

2.函数练习

  四个小练习把「参数 + 多分支 + 返回值」串起来:①判断闰年(能被 4 整除但不能被 100 整除,或能被 400 整除);②根据年/月算天数(注意 2 月闰年 29 天、平年 28 天);③按月份返回季节;④判断质数(2 到 n-1 都不能整除)。下面代码修正了两处原笔记笔误——leap_year 返回值其实是 bool 不是 str;原 month_days 把闰年 2 月天数写反了,已改正。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 1.封装一个函数 验证一个年是否是闰年
## 闰年的条件or:1.能被4整除但是不能被100整除
# 2.能被400整除
# 条件1和条件2满足一个即可

def leap_year(year) -> bool:
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
print(f'{year}是闰年')
return True
else:
print(f'{year}不是闰年')
return False

leap_year(2025)

# 2.封装一个函数,获取指定月的天数、
# 注意 闰年2月有29天
def month_days(year, month) -> int:
if month == 2:
if leap_year(year):
return 29 # 修正:闰年2月=29天
else:
return 28 # 修正:平年2月=28天
elif month == 4 or month == 6 or month == 9 or month == 11:
return 30
else:
return 31

day = month_days(2026, 8)
print(f'{2026}年8月有{day}天')

# 3.封装一个函数 获取指定月所属的季节:多分支
# 3、4、5春季 6、7、8夏季 9、10、11秋季 12、1、2冬季
def season(month) -> str:
if month in [3, 4, 5]:
return '春季'
elif month in [6, 7, 8]:
return '夏季'
elif month in [9, 10, 11]:
return '秋季'
else:
return '冬季'

print(f'8月是{season(8)}')

# 4.封装一个函数 验证指定数是否是质数
# 注意:质数:在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
def is_prime(num) -> str:
if num <= 1:
return '不是质数'
for i in range(2, num):
if num % i == 0:
return '不是质数'
return '是质数'
print(is_prime(13))

 

3.函数嵌套

  这一节其实讲了两个容易混淆的点:函数嵌套定义(在函数里再定义函数,外层返回内层)和函数名即变量(函数名本身是个指向函数对象的变量,可以赋值给别的名字、用新名字调用)。fn1 内部定义了 fn2 并返回它——所以 f2 = fn1(10) 拿到的是 fn2,再 f2(20) 才真正执行内层;f3 = fn3 则是把函数对象换了个引用名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 函数的嵌套

# 函数名称即是函数名,也是指向该函数的变量
def fn1(x):
print(f'fn1函数中的x:{x}')

def fn2(y):
print(f'fn2函数中的y:{y}')
return fn2

f2=fn1(10)
f2(20)


def fn3(x):
print(f'fn3函数中的x:{x}')

fn3(30)
f3 = fn3
f3(40)

 

4.匿名函数

  lambda 是匿名函数:没有名字、自带 return、只适合写「一行就能表达、且有返回值」的小函数。lambda 参数: 表达式 整体就是一个函数对象,常当作参数传给 map/filter 这类高阶函数(接收函数或返回函数的函数)。map 对可迭代对象逐个映射,filter 按条件过滤保留。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 匿名函数 lambda
# 特点:
# 没有函数名称
# 自带return
# 只表示一些简单的,有返回值的函数
f = lambda x: x**2
print(f(3))

f2 = lambda x, y: x**y
print(f2(3, 2))


# 高阶函数 是一个函数作为参数,或者返回一个函数的函数。

# map:映射,对列表做批量处理
n = map(lambda x: x**2, [1, 2, 3, 4])
print(list(n)) # 输出:[1, 4, 9, 16] 修正:list() 后为列表

n2 = map(lambda x,y: x**y, [1, 2, 3, 4], [2, 3, 4, 5])
print(list(n2)) # 输出:[1, 8, 81, 1024]

# filter:过滤,对列表做批量处理
n3 = filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(list(n3)) # 输出:[2, 4, 6, 8, 10]

 

5.回调函数

  回调函数就是把函数当作参数传进另一个函数,由后者在合适时机「回过头来调用」它。fn(3, lambda x: x**2) 里 lambda 就是回调。自己实现 filter_cb 能看清原理:遍历列表,用回调判断每个元素是否保留。sort(key=lambda) 则让排序按「提取出的某个键」来进行,比如按字典的 age 升序、按 score 降序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 回调函数
# 把函数当做参数传入到另一个函数中

def fn(n, cb): #cb: callback 回调函数
print('fn函数中的n:', n)
n2 = cb(n)
print('fn函数中的n2:', n2)


fn(3, lambda x: x**2)

# 自定义过滤器
# filter:过滤,找到符合要求的数据
# n = filter(lambda x:x>0, [1, -2,3, -4, -5,7,6, -9])
def filter_cb(cb, l):
l2 = []
for i in l:
if cb(i):
l2.append(i)
return l2

n = filter_cb(lambda x:x>0, [1, -2,3, -4, -5,7,6, -9])
print(n)


# sort(key=lambda)
list1 = [
{'name': '张三', 'age': 18, 'score': 50, 'tel': '18866669999', 'sex': '不明'},
{'name': '李四', 'age': 16, 'score': 88, 'tel': '18866668998', 'sex': '男'},
{'name': '王五', 'age': 17, 'score': 48, 'tel': '18866667995', 'sex': '女'},
{'name': '陈一军', 'age': 61, 'score': 59, 'tel': '18866669998', 'sex': '不明'},
{'name': '陈二军', 'age': 49, 'score': 88, 'tel': '18866669396', 'sex': '男'},
{'name': '陈三军', 'age': 49, 'score': 61, 'tel': '18866668994', 'sex': '女'}
]
# 要求1:把 list1 按照 age 升序
list1.sort(key=lambda x: x['age'])
print(list1)


# 需求2:把 list1 按照 score 降序
list1.sort(key=lambda x: x['score'], reverse=True)
print(list1)

 

6.函数作业

  四道综合作业:①回文判断(转字符串后倒序比较);②用 *args 一次性拿到最小值 / 最大值 / 和 / 平均数;③在②基础上统计「高于平均数」的个数;④穷举 100–999 拆出百十个位,求水仙花数(各位立方和等于自身)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 1.封装一个函数,验证一个数是否是回文
def is_palindrome(n) -> bool:
n = str(n)
n2 = n[::-1]
if n == n2:
return True
else:
return False
print(is_palindrome(12321))
print(is_palindrome(12345))


# 2.封装一个函数,获取多个数中的最小值,最大值,和 以及平均数
def get_min_max_avg(*args) -> tuple:
min_val = min(args)
max_val = max(args)
sum_val = sum(args)
avg_val = sum_val / len(args)
return min_val, max_val, sum_val, avg_val

print(get_min_max_avg(1, 2, 3, 4, 5))


# 3,.封装一个函数,获得多个数中的平均值,并统计其中高于平均数的值的个数
def get_avg_count(*args) -> tuple:
avg_val = sum(args) / len(args)
count = 0
for i in args:
if i > avg_val:
count += 1
return avg_val, count

print(get_avg_count(1, 2, 3, 4, 5))

# 4.封装一个函数,获取所有的水仙花数
# 水仙花数是指一个三位数,它的每个数字的立方之和等于它本身
def get_armstrong_numbers() -> list:
l = []
for i in range(100, 1000):
a = i // 100 # 百位数
b = (i - a * 100) // 10 # 十位数
c = i % 10 # 个位数
if a**3 + b**3 + c**3 == i:
l.append(i)
return l
print(get_armstrong_numbers())

智泊Python--Day8
https://one-null-pointer.github.io/2026/07/27/智泊Python--Day8/
Author
liaoyue
Posted on
July 27, 2026
传送口