1️⃣ 函数也是对象
# 函数也是对象
a1 = 100 # a1是int类型的实例
a2 = 'hellp' # a2是str类的实例
a3 = [10, 20, 30] # a4是list类的实例
# welcome函数是function类的实例对象
def welcome():
print("你好,Python")
print(type(a1)) # <class 'int'>
print(type(a2)) # <class 'str'>
print(type(a3)) # <class 'list'>
print(type(welcome)) # <class 'function'>
上面代码中 welcome 函数的内存示意图:

2️⃣ 函数可以像对象一样,动态添加属性
def welcome():
print("你好,Python")
# 动态添加属性
welcome.desc = '这是一个用户打招呼的函数'
welcome.version = '1.0'
print(welcome.__dict__)
# 调用函数
welcome()
上述代码的内存结构示意图:

3️⃣ 函数可以赋值给变量
def welcome():
print("你好,Python")
# 把函数对象赋值给变量
say_hello = welcome
# 通过变量调用函数
say_hello()
# 通过函数名调用函数
welcome()
上述代码的结构示意图:

4️⃣ 可变参数 vs 不可变参数
不可变参数 代码示例:
def welcome(data):
print(f'函数收到的data是:{data},地址是:{id(data)}')
data = 999
print(f'被修改后的data是:{data},地址是:{id(data)}')
a = 666
print(f'函数外侧a的值是:{a},地址是:{id(a)}')
welcome(a)
print(f'函数调用后a的值是:{a},地址是:{id(a)}')
可变参数 代码示例:
def welcome2(data):
print(f'函数收到的data是:{data},地址是:{id(data)}')
data[2] = 999
print(f'被修改后的data是:{data},地址是:{id(data)}')
a = [10, 20, 30]
print(f'函数外侧a的值是:{a},地址是:{id(a)}')
welcome2(a)
print(f'函数调用后a的值是:{a},地址是:{id(a)}')
5️⃣ 函数也可以作为参数
def welcome():
print("你好,Python")
def caller(func):
print('caller函数开始调用')
func()
caller(welcome)
6️⃣ 函数也可以作为返回值
def welcome():
print('你好啊')
def show_message():
print('你好python')
return show_message
result = welcome()
result()
# 换种写法
welcome()()
在函数内的return关键字后面写多个值,并且多个值之间用逗号隔开,Python 会自动把多个值打包成元组。
def calculate(x, y):
res1 = x + y
res2 = x - y
return res1, res2 # 实际返回的结果是:(res1, res2)
result = calculate(1, 2)
print(result, type(result)) # (3, -1) <class 'tuple'>
r1, r2 = calculate(1, 2) # 直接解包
print(r1, r2) # 3 -1
定义函数时,打包接收参数:
*形参名:打包所有的位置参数,形成一个元组。**形参名:打包所有的关键字参数,形成一个字典。调用函数时,解包传递参数:
*变量名:将元组拆解成一个一个独立的位置参数。**变量名:将字典拆解成一个一个key=value形式的关键字参数。示例代码:
def show_info(*args, **kwargs):
print(type(args), args) # <class 'tuple'> (10, 20, 30)
print(type(kwargs), kwargs) # <class 'dict'> {'name': '张三', 'age': 41}
nums = (10, 20, 30)
person = {'name': '张三', 'age': 41}
show_info(*nums, **person)
当一个函数的『参数是函数』或者『返回值是函数』,那么该函数就是高阶函数。
示例代码:
def welcome():
print("你好啊")
# 函数作为参数
def caller(f):
print('caller函数开始调用')
f()
caller(welcome)
# 函数作为返回值
def outer():
print('我是outer')
def inner():
print('inner')
return inner
outer()()
高阶函数意义:
❏ 代码复用性高:可以把行为“独立出去”,传入不同函数实现不同逻辑。
❏ 能让函数更灵活,更通用。
❏ 高阶函数是:装饰器、闭包的基础。(后续文章详解)
高阶函数的一个小应用:
def info(msg):
return '【提示】' + msg
def warn(msg):
return '【警告】' + msg
def error(msg):
return '【错误】' + msg
def log(func, text):
print(func(text))
log(info, '文件保存成功!')
log(warn, '磁盘空间不足!')
log(error, '该用户不存在!')
❔什么是表达式:执行后最终能得到一个值的代码,就是表达式,示例如下:
3 + 5
'abc' * 3
5 > 3
'y' in 'python'
len('hello')
条件表单式:根据不同的条件得到不同的值,又称:三元运算符 或 三目运算符。语法格式如下:
结果1 if 条件 else 结果2
语义解释:如果条件为真,整个表达式的结果就是“结果1”,否则就是“结果2”。
示例代码:
age = 20
# if-else的写法
if age >= 18:
text = '成年'
else:
text = '未成年'
print(text)
# 条件表达式的写法
text = '成年' if age >= 18 else '未成年'
print(text)
概念:所谓匿名函数,就是没有名字的函数,它无需使用def关键字去定义。
语法:Python 中使用lambda关键字来定义匿名函数,格式为:lamdba 参数: 表达式
使用场景:当一个函数只用一次,使用匿名函数会更简洁。
下面的示例代码展示同样的功能,分别使用普通函数与匿名函数实现:
def add(a, b):
return a + b
def sub(a, b):
return a - b
def calculate(func, a, b):
print(f'计算结果为:{func(a, b)}')
calculate(add, 2, 3)
calculate(sub, 2, 3)
def calculate(func, a, b):
print(f'计算结果为:{func(a, b)}')
# 使用匿名函数
calculate(lambda a, b: a + b, 1, 2)
calculate(lambda a, b: a - b, 1, 2)
特点:
示例代码(匿名函数 + 条件表达式):
is_adult = lambda age: '成年' if age >= 18 else '未成年'
print(is_adult(18))
print(is_adult(13))
map函数:对一组数据中的每一个元素,统一执行某种操作(加工),并生成一组新数据。
语法格式:map(操作函数, 可迭代对象)。
注意点:
map函数返回的是一个迭代器对象,需要我们去手动遍历,或者手动转换类型。示例代码:
# 统一数据处理
nums1 = [10, 20, 30, 40]
result = map(lambda x: x * 2, nums1)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(list(result)) # [20, 40, 60, 80]
print(nums1) # [10, 20, 30, 40]
# 字符串格式化
names = ('python', 'java', 'ts')
result = map(lambda x: x.upper(), names)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(tuple(result)) # ('PYTHON', 'JAVA', 'TS')
print(list(result)) # [] ??为什么为空呢?原因是迭代器对象上一行代码已经遍历过了,就会“耗尽”了
print(names) # ('python', 'java', 'ts')
# 类型转换
str_num = {'1', '2', '3', '4'}
result = map(int, str_num)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(set(result)) # {1, 2, 3, 4}
print(str_num) # {'1', '2', '3', '4'}
# 验证:map返回的迭代器对象,一旦遍历完成,就会被“耗尽”
num2 = [10, 20, 30]
result = map(lambda x: x * 3, num2)
print(type(result), result)
print(list(result))
print(list(result))
print(list(result))
print(num2)
filter函数:从一组数据中,筛选出符合条件的元素(过滤),并形成一组新数据。
语法格式:filter(操作函数, 可迭代对象)。
注意点:
示例代码:
# 筛选数值
nums = [10, 20, 30, 40, 50]
result = filter(lambda n: n > 20, nums)
print(type(result), result) # <class 'filter'> <filter object at 0x0000020D5A43BA00>
print(list(result)) # [30, 40, 50]
print(list(result)) # []
print(nums) # [10, 20, 30, 40, 50]
# 筛选成年人
persons = [
{'name': '张三', 'age': 15, 'gender': '男'},
{'name': '李四', 'age': 16, 'gender': '女'},
{'name': '王五', 'age': 21, 'gender': '男'},
{'name': '李华', 'age': 18, 'gender': '女'},
{'name': '赵六', 'age': 19, 'gender': '女'},
{'name': '孙琪', 'age': 20, 'gender': '男'},
]
result = filter(lambda p: p['age'] > 19, persons)
print(type(result), result) # <class 'filter'> <filter object at 0x000001C71B0DCA00>
print(list(result)) # [{'name': '王五', 'age': 21, 'gender': '男'}, {'name': '孙琪', 'age': 20, 'gender': '男'}]
print(list(result)) # []
# 过滤非法字符串
names = ['张三', '', '李四', None, '王五']
result = filter(lambda n: n, names)
print(type(result), result) # <class 'filter'> <filter object at 0x000001BDC7BACDC0>
print(list(result)) # ['张三', '李四', '王五']
print(list(result)) # []
# 如果不传递过滤函数,那么自动会过滤掉“假值”
data = [0, 1, '', 'hello', [], (), 5]
result = filter(None, data)
print(type(result), result) # <class 'filter'> <filter object at 0x00000187AB71D0F0>
print(list(result)) # [1, 'hello', 5]
sorted函数:对一组数据进行排序,返回一组新数据。注意该函数返回值是列表类型。
语法格式:sorted(可迭代对象, key=xxxx, reverse=xxxx)。
# 数字排序
nums = tuple([40, 60, 30, 50])
print(type(nums), nums) # <class 'tuple'> (40, 60, 30, 50)
result = sorted(nums)
print(type(result), result) # <class 'list'> [30, 40, 50, 60]
print(sorted(nums, reverse=True)) # [60, 50, 40, 30]
# 按照字符串长度排序
names = ['python', 'sql', 'java']
result = sorted(names, key=len, reverse=False)
print(type(result), result) # <class 'list'> ['sql', 'java', 'python']
# 根据字典中的某个字段进行排序
persons = [
{'name': '张三', 'age': 15, 'gender': '男'},
{'name': '李四', 'age': 16, 'gender': '女'},
{'name': '王五', 'age': 21, 'gender': '男'},
{'name': '李华', 'age': 18, 'gender': '女'},
{'name': '赵六', 'age': 19, 'gender': '女'},
{'name': '孙琪', 'age': 20, 'gender': '男'},
]
result = sorted(persons, key=lambda p: p['age'], reverse=True)
print(type(result),
result) # <class 'list'> [{'name': '王五', 'age': 21, 'gender': '男'}, {'name': '孙琪', 'age': 20, 'gender': '男'}, {'name': '赵六', 'age': 19, 'gender': '女'}, {'name': '李华', 'age': 18, 'gender': '女'}, {'name': '李四', 'age': 16, 'gender': '女'}, {'name': '张三', 'age': 15, 'gender': '男'}]
拓展:我们之前学过的max函数,min函数,也可以传递key参数,用于设置筛选依据。
persons = [
{'name': '张三', 'age': 15, 'gender': '男'},
{'name': '李四', 'age': 16, 'gender': '女'},
{'name': '王五', 'age': 21, 'gender': '男'},
{'name': '李华', 'age': 18, 'gender': '女'},
{'name': '赵六', 'age': 19, 'gender': '女'},
{'name': '孙琪', 'age': 20, 'gender': '男'},
]
result = max(persons, key=lambda p: p['age'])
print(type(result), result) # <class 'dict'> {'name': '王五', 'age': 21, 'gender': '男'}
result = min(persons, key=lambda p: p['age'])
print(type(result), result) # <class 'dict'> {'name': '张三', 'age': 15, 'gender': '男'}
reduce函数:将一组数据不断“合并”,最终归并成一个结果。
语法格式:reduce(合并函数,可迭代对象, 初始值)。
注意:reduce 函数需要从 functools 模块中引入才能使用。
# 从 functools 模块中引入 reduce
from functools import reduce
# 数值统计
nums = [1, 2, 3, 4, 5]
result = reduce(lambda a, b: a + b, nums)
print(type(result), result) # <class 'int'> 15
result = reduce(lambda a, b: a + b, nums, 100)
print(type(result), result) # <class 'int'> 115
# 拼接字符串
str_list = ['ab', 'cd', 'ef']
result = reduce(lambda a, b: a + b, str_list)
print(type(result), result) # <class 'str'> abcdef
result = reduce(lambda a, b: a + b, str_list, '**')
print(type(result), result) # <class 'str'> **abcdef
🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。