函数
目录
一、容器知识补充
1、字典遍历方法
当要遍历字典的元素内容,即获取字典的键、值。
常用方法:
函数名 | 含义 |
---|---|
keys() | 以列表的形式,返回一个字典所有的键。 |
values() | 以列表的形式,返回一个字典所有的值。 |
items() | 返回由键值组成的序列,主要应用于遍历字典。 |
为便于理解几个方法,可简要理解为:
2、遍历字典元素
keys()方法:
函数名 | 含义 |
---|---|
keys() | 以列表的形式,返回一个字典所有的键。 |
在Python中,字典(dictionary)的keys()
函数返回的是一个字典视图对象(dictionary view object),具体来说是"字典键视图"(dictionary keys view)。
这个视图对象是一个动态集合,它展示了字典的键。这个视图对象支持集合操作,如迭代、成员检查等,但它不是列表或元组。
说明:
获取所有键内容,可以当做列表进行处理。
values()方法:
函数名 | 含义 |
---|---|
values() | 以列表的形式,返回一个字典所有的值。 |
说明:
获取所有值,可以当做列表处理。
items()方法:
函数名 | 含义 |
---|---|
items() | 返回由键值组成的序列,主要应用于遍历字典。 |
说明 :
获取所有的键值。
例如,一起来完成:
(1)定义一个字典变量,存放一个学生的信息:姓名、住址、年龄等;
(2)获取字典变量中的所有键,并输出【键 --> 值】形式结果;
(3)获取字典变量中的所有值并输出;
(4)获取字典变量中的所有键、值序列;
(5)执行程序,观察效果。
python
datas = {"name": "张三丰",
"address": "武当山",
"age": 147}
print('--------1、获取所有的键----------------')
# keys()获取所有的键,得到一个字典视图对象
print(datas.keys()) # 获取的是一个对象,内部包含列表:dict_keys(['name', 'address', 'age'])
print(list(datas.keys())) # 得到列表: ['name', 'address', 'age']
print('--------2、遍历-方式1----------------')
# 遍历-方式1
for key in datas.keys(): #遍历时,不需要将keys()获取的内容进行列表转换,直接遍历即可
print(key+'------'+str(datas.get(key)))
print('--------4、获取所有的键值对项----------------')
print(datas.items()) #dict_items([('name', '张三丰'), ('address', '武当山'), ('age', 147)])
print('--------3、遍历-方式2----------------')
for kv in datas.items(): # kv就是一个元组: ('name', '张三丰')
print(kv[0]+'-----------'+str(kv[1]))
print('--------4、获取所有的值----------------')
#values() 得到一个字典视图对象
print(datas.values()) # dict_values(['张三丰', '武当山', 147])
print(list(datas.values())) # ['张三丰', '武当山', 147]
3、公共运算符
公共运算符指的是:可以运用于Python容器的一下运算符。
常见公共运算符:
运算符 | 描述 | 支持的容器类型 |
---|---|---|
+ | 合并 | 字符串、列表、元组 |
* | 复制 | 字符串、列表、元组 |
in | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 元素是否不存在 | 字符串、列表、元组、字典 |
例如,一起来完成:
(1)定义字符串变量,并完成+、*的运算操作;
(2)定义列表变量,并完成in、not in的运算操作。
python
print('---------运算符:+-----------------')
# ------字符串-----
str1 = 'hello'
str2 = 'world'
num = 123
print(str1 + str2) # +两端只能跟字符串
print(str1 + str(num)) # +两端只能跟字符串,否则需要进行类型强转
# -----列表-----
list1 = [1,2,3]
list2 = [3,4,5,6]
list3 = list1 + list2
print(list1) # list1不变
print(list2) # list2不变
print(list3) # list3为list1和list2合并后的结果
# 以下方式也可以将list1和list2进行合并
list1.extend(list2)
print(list1)
# -----元组-----
tuple1 = (1,2,3)
tuple2 = (3,4,5,6)
tuple3 = tuple1 + tuple2
print(tuple1)
print(tuple2)
print(tuple3) # tuple3为tuple1和tuple2合并后的结果
print('---------运算符:* -----------------')
str1 = 'itcast'
print(str1 * 10) # 让str1重复10次
list1 = [1,2,3]
print(list1 * 10) # 列表的内容被复制10倍
tuple1 = (1,2,3)
print(tuple1 * 10)
print('---------运算符: in和not in -----------------')
# -----字符串
str1 = 'I love itcast'
if 'v' in str1:
print('字符v在字符串中')
else:
print('字符v不在字符串中')
# -----列表
list1 = ['刘备','关羽','张飞']
if '关羽' in list1:
print('关羽在列表中')
else:
print('关羽不在列表中')
# -----字典
dict1 = {'name':'刘备','age':18}
if 'age' not in dict1:
print('age这个键在字典中')
else:
print('age这个键不在字典中')
4、公共方法
公共方法指的是:能适用于Python容器的一些通用方法。
常见公共方法:
描述 | |
---|---|
len(s) | 计算容器中的元素总个数 |
del | 删除 |
max() | 返回容器中元素最大值 |
min() | 返回容器中元素最小值 |
例如,一起来完成:
(1)定义一个列表变量,内容为:10、300、20、200、30、100、0;
(2)获取列表变量的总长度;
(3)获取列表的最大值和最小值;
(4)思考:为何有些方法可直接使用,比如:max()、len(),而大多数方法都需要使用【变量名.函数(xx)】形式调用?
python
# 1.定义变量
list1 = [10,300,20,200,30,100,0]
# 2.长度
print(len(list1))
# 3.最大最小值
print(max(list1))
print(min(list1))
# 4.删除元素
del list1[1]
print(list1)
# 5、查看Python所有的内置函数
print(dir(__builtins__))
注意:当要查看Python内置[函数]有哪些时,可以使用dir(builtins)来查看。
二、函数介绍
1、函数的概念
在Python函数中,有几个重要概念:
(1)函数名
(2)参数
(3)返回值
为了更好的理解函数的几个概念。通过【我给钱让儿子帮我买包烟】为例说明。
整个过程:我给钱给我儿子,然后儿子帮我去买烟,最后他成功把烟拿给了我。
比如,买烟可以比作为一个函数名,那么给的钱就看作是参数,最终儿子拿给我的烟可以比作是返回值。
python
买烟(钱):
...[买烟过程]
返回: 烟
函数语法:
def 函数名(参数, ..):
代码1
代码2
...
[return 具体的值]
总结:
(1)当将一些代码进行封装在一块,并给这块代码取了个名字,就叫做函数;
(2)定义函数时,需要使用def关键字。
2、引入函数
据说,项目开发前运行【佛祖镇楼】案例,可以减少项目Bug,一起看看。
比如,某个程序在不同的条件下,要输出【佛祖镇楼】,那么,程序可以使用if语句判断处理:
python
if 条件1:
输出"佛祖镇楼"
......
elif 条件2:
输出"佛祖镇楼"
......
elif 条件3:
输出"佛祖镇楼"
......
......(省略)
仔细观察,我们会发现:需要输出多次的【佛祖镇楼】。
此时,就可以使用函数解决重复编写代码的问题。
例如,一起来完成:
(1)当从键盘上输入数值1-6之间的某个自然数时,则输出【佛祖镇楼】;
(2)使用函数形式改进程序;
(3)对比两个程序代码并执行,观察效果。
python
# # 1.定义变量
# number = int(input("请输入数字:"))
# # 2.判断
# if number == 1:
# # 3.输出
# print(" _ooOoo_ ")
# print(" o8888888o ")
# print(" 88 . 88 ")
# print(" (| -_- |) ")
# print(" O\\ = /O ")
# print(" ____/`---'\\____ ")
# print(" . ' \\| |// `. ")
# print(" / \\||| : |||// \\ ")
# print(" / _||||| -:- |||||_ \ ")
# print(" | | \\\\\\ - /// | | ")
# print(" | \\_| ''\\---/'' | | ")
# print(" \\ ..\__ `-` ___/-. / ")
# print(" ___`. .' /--.-.\ `. . __ ")
# print(" ."" '< `.___\\_<|>_/___.' >'"". ")
# print(" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | ")
# print(" \\ \\ `-. \\_ __\\ /__ _/ .-` / / ")
# print(" ======`-.____`-.___\\_____/___.-`____.-'====== ")
# print(" `=---=' ")
# print(" ")
# print(" ............................................. ")
# print(" .........佛祖镇楼...................bug辟易...")
# print(" 佛曰: ")
# print(" 写字楼里写字间,写字间里程序员; ")
# print(" 程序人员写程序,又拿程序换酒钱。 ")
# print(" 酒醒只在网上坐,酒醉还来网下眠; ")
# print(" 酒醉酒醒日复日,网上网下年复年。 ")
# print(" 但愿老死电脑间,不愿鞠躬老板前; ")
# print(" 奔驰宝马贵者趣,公交自行程序员。 ")
# print(" 别人笑我太疯癫,我笑自己命太贱; ")
# print(" 不见满街漂亮妹,哪个归得程序员?")
# elif number == 2:
# print(" _ooOoo_ ")
# print(" o8888888o ")
# print(" 88 . 88 ")
# print(" (| -_- |) ")
# print(" O\\ = /O ")
# print(" ____/`---'\\____ ")
# print(" . ' \\| |// `. ")
# print(" / \\||| : |||// \\ ")
# print(" / _||||| -:- |||||_ \ ")
# print(" | | \\\\\\ - /// | | ")
# print(" | \\_| ''\\---/'' | | ")
# print(" \\ ..\__ `-` ___/-. / ")
# print(" ___`. .' /--.-.\ `. . __ ")
# print(" ."" '< `.___\\_<|>_/___.' >'"". ")
# print(" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | ")
# print(" \\ \\ `-. \\_ __\\ /__ _/ .-` / / ")
# print(" ======`-.____`-.___\\_____/___.-`____.-'====== ")
# print(" `=---=' ")
# print(" ")
# print(" ............................................. ")
# print(" .........佛祖镇楼...................bug辟易...")
# print(" 佛曰: ")
# print(" 写字楼里写字间,写字间里程序员; ")
# print(" 程序人员写程序,又拿程序换酒钱。 ")
# print(" 酒醒只在网上坐,酒醉还来网下眠; ")
# print(" 酒醉酒醒日复日,网上网下年复年。 ")
# print(" 但愿老死电脑间,不愿鞠躬老板前; ")
# print(" 奔驰宝马贵者趣,公交自行程序员。 ")
# print(" 别人笑我太疯癫,我笑自己命太贱; ")
# print(" 不见满街漂亮妹,哪个归得程序员?")
# elif number == 3:
# print(" _ooOoo_ ")
# print(" o8888888o ")
# print(" 88 . 88 ")
# print(" (| -_- |) ")
# print(" O\\ = /O ")
# print(" ____/`---'\\____ ")
# print(" . ' \\| |// `. ")
# print(" / \\||| : |||// \\ ")
# print(" / _||||| -:- |||||_ \ ")
# print(" | | \\\\\\ - /// | | ")
# print(" | \\_| ''\\---/'' | | ")
# print(" \\ ..\__ `-` ___/-. / ")
# print(" ___`. .' /--.-.\ `. . __ ")
# print(" ."" '< `.___\\_<|>_/___.' >'"". ")
# print(" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | ")
# print(" \\ \\ `-. \\_ __\\ /__ _/ .-` / / ")
# print(" ======`-.____`-.___\\_____/___.-`____.-'====== ")
# print(" `=---=' ")
# print(" ")
# print(" ............................................. ")
# print(" .........佛祖镇楼...................bug辟易...")
# print(" 佛曰: ")
# print(" 写字楼里写字间,写字间里程序员; ")
# print(" 程序人员写程序,又拿程序换酒钱。 ")
# print(" 酒醒只在网上坐,酒醉还来网下眠; ")
# print(" 酒醉酒醒日复日,网上网下年复年。 ")
# print(" 但愿老死电脑间,不愿鞠躬老板前; ")
# print(" 奔驰宝马贵者趣,公交自行程序员。 ")
# print(" 别人笑我太疯癫,我笑自己命太贱; ")
# print(" 不见满街漂亮妹,哪个归得程序员?")
# elif number == 4:
# print(" _ooOoo_ ")
# print(" o8888888o ")
# print(" 88 . 88 ")
# print(" (| -_- |) ")
# print(" O\\ = /O ")
# print(" ____/`---'\\____ ")
# print(" . ' \\| |// `. ")
# print(" / \\||| : |||// \\ ")
# print(" / _||||| -:- |||||_ \ ")
# print(" | | \\\\\\ - /// | | ")
# print(" | \\_| ''\\---/'' | | ")
# print(" \\ ..\__ `-` ___/-. / ")
# print(" ___`. .' /--.-.\ `. . __ ")
# print(" ."" '< `.___\\_<|>_/___.' >'"". ")
# print(" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | ")
# print(" \\ \\ `-. \\_ __\\ /__ _/ .-` / / ")
# print(" ======`-.____`-.___\\/___.-`____.-'====== ")
# print(" `=---=' ")
# print(" ")
# print(" ............................................. ")
# print(" .........佛祖镇楼...................bug辟易...")
# print(" 佛曰: ")
# print(" 写字楼里写字间,写字间里程序员; ")
# print(" 程序人员写程序,又拿程序换酒钱。 ")
# print(" 酒醒只在网上坐,酒醉还来网下眠; ")
# print(" 酒醉酒醒日复日,网上网下年复年。 ")
# print(" 但愿老死电脑间,不愿鞠躬老板前; ")
# print(" 奔驰宝马贵者趣,公交自行程序员。 ")
# print(" 别人笑我太疯癫,我笑自己命太贱; ")
# print(" 不见满街漂亮妹,哪个归得程序员?")
# 代码很多重复? -->不好维护
def show_no_bug():
# 3.输出
print(" _ooOoo_ ")
print(" o8888888o ")
print(" 88 . 88 ")
print(" (| -_- |) ")
print(" O\\ = /O ")
print(" ____/`---'\\____ ")
print(" . ' \\| |// `. ")
print(" / \\||| : |||// \\ ")
print(" / _||||| -:- |||||_ \ ")
print(" | | \\\\\\ - /// | | ")
print(" | \\_| ''\\---/'' | | ")
print(" \\ ..\__ `-` ___/-. / ")
print(" ___`. .' /--.-.\ `. . __ ")
print(" ."" '< `.___\\_<|>_/___.' >'"". ")
print(" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | ")
print(" \\ \\ `-. \\_ __\\ /__ _/ .-` / / ")
print(" ======`-.____`-.___\\_____/___.-`____.-'====== ")
print(" `=---=' ")
print(" ")
print(" ............................................. ")
print(" .........佛祖镇楼...................bug辟易...")
print(" 佛曰: ")
print(" 写字楼里写字间,写字间里程序员; ")
print(" 程序人员写程序,又拿程序换酒钱。 ")
print(" 酒醒只在网上坐,酒醉还来网下眠; ")
print(" 酒醉酒醒日复日,网上网下年复年。 ")
print(" 但愿老死电脑间,不愿鞠躬老板前; ")
print(" 奔驰宝马贵者趣,公交自行程序员。 ")
print(" 别人笑我太疯癫,我笑自己命太贱; ")
print(" 不见满街漂亮妹,哪个归得程序员?")
# 1.定义变量
number = int(input("请输入数字:"))
# 2.判断
if number == 1:
show_no_bug()
elif number == 2:
show_no_bug()
elif number == 3:
show_no_bug()
elif number == 4:
show_no_bug()
# 解决了代码重复问题;
# 提升了代码阅读能力
总结:
(1)当要减少代码的重复和代码冗余时,就可以使用Python函数;
(2)请问:使用函数可以提升代码的阅读性,这句话正确吗?
3、函数定义与调用
Python函数需要使用def关键字来定义。使用方式有两步:
(1)先定义
(2)后调用
当然了,函数在使用时,特点:
(1)先定义,后调用;
(2)不调用,不执行;
(3)调用一次,执行一次。
接着,来一起看看函数的语法。
定义函数:
def 函数名():
代码1
代码2 ...
调用函数:
函数名()
例如,一起来完成:
(1)编写一个show()函数,并在函数中输出:bug虐我千百遍, 我待bug如初恋。
(2)调用函数,观察执行结果。
4、函数的参数
当在定义函数时,设定了参数,则可称该函数为:有参函数。反之,没有参数的函数,称为:无参函数。
定义有参数的函数,语法:
python
def 函数名(参数1,参数2,...): # 形参
代码1
代码2
...
调用函数,语法:
python
函数名(参数值1,参数值2,...) # 实参
说明:
(1)形参是指形式参数,表示在定义函数时的参数;
(2)实参是指实际参数,表示在调用函数时传递的参数值,具有实际意义。
例如,一起来完成:
(1)定义一个函数,用于求解两个数之和;
(2)接着,调用函数并执行程序,观察效果。
python
# 1.定义函数
def get_sum(a,b):
ret = a + b
print(f"两个数之和为:{ret}")
# 2.调用函数
get_sum(10,20)
# get_sum(90) # 报错
总结:
(1)当定义了有参数的函数时,调用函数也需要传递参数值;
(2)注意:当给有参函数传递参数时,要关注参数的三要素:个数、类型、顺序。
5、函数的返回值
函数的返回值指的是:当函数完成一件事情后,最后要返回给函数的结果。
返回值语法:
python
def 函数名([参数1, 参数2, ...]):
代码1
代码2
...
return 值
说明:
(1)若要给函数返回结果,需要使用return关键字;
(2)return关键字的作用:把结果返回给函数;结束函数;
(3)当函数没有返回值时,默认返回None。
python
print('-----------无参,无返回值-------------')
# 1、定义函数-无参,无返回值
def show():
print('这是一个函数,无参,无返回值')
# 2、调用函数
show()
show()
print('-----------有参,有返回值-------------')
# 1、定义函数:有参,有返回值 --->求两个数的和
# 该函数没有限定参数类型,理论上可以传入任何类型,但是可能会报错
def get_sum(num1, num2): # 形参
return num1 + num2
# 该函数限定参数类型必须是int,返回值也是int,一般封装系统级函数时,可以使用
def get_sum2(num1: int, num2: int) -> int: # 形参
return num1 + num2
# 2、调用函数
# 方式1
result1 = get_sum(10, 20) # 实参
print(result1)
# 方式2
print(get_sum(10, 20)) # 实参
print(get_sum('hello', 'world'))
# print(get_sum2('hello', 'world')) # 报错,类型不一致
print('-----------有参, 无返回值-------------')
# 如果一个函数没有指定返回值,默认会在函数尾部加:return None
# 1、定义函数
def func1(num):
for i in range(num):
print('********************')
# 2、调用函数
func1(5)
print('-----------无参, 有返回值-------------')
# 1、定义函数
import random
def get_random_number_between_1_and_100():
return random.randint(1, 100)
# 2、调用函数
print(get_random_number_between_1_and_100())
总结:
(1)当函数没有返回值时,在函数内部代码最后一行会有默认代码:return None
(2)注意:return关键字的作用有两个:(一)把结果返回给函数;(二)结束函数。
-
函数返回多个值
python# 需求:定义一个函数,传入一个数字列表,返回列表的最大值,最小值,平均值 # 1、定义函数 def get_list_result(list_name): max_value = max(list_name) min_value = min(list_name) avg_value = sum(list_name) / len(list_name) return max_value, min_value, avg_value # 返回的时元组 # 2、调用函数 list1 = [1, 2, 3, 4, 5, 30, 50] result = get_list_result(list1) print(type(result)) # <class 'tuple'> print(f'最大值:{result[0]}') # 使用索引来访问元组中的元素 print(f'最小值:{result[1]}') # 使用索引来访问元组中的元素 print(f'平均值:{result[2]}') # 使用索引来访问元组中的元素
6、说明文档
说明文档指的是:在定义函数的第一行,加上多行注释。这样的操作,可以让函数更加规范化。
当添加了说明文档后,在调用函数时,就能查看到函数的作用提示。
说明:
查看下print()函数。
接着,一起来看看在自定义函数时,如何给函数添加说明文档?
添加说明文档的语法:
python
def 函数名():
""" 说明文档的位置 """
代码
...
当需要看函数的说明文档的具体内容时,语法:
python
help(函数名)
python
# 1、定义函数时,给函数加说明书
def get_list_result(list_name):
"""
这是一个获取列表信息的函数
:param 列表名
:return: 最大值、最小值、平均值
"""
max_value = max(list_name)
min_value = min(list_name)
avg_value = sum(list_name) / len(list_name)
return max_value, min_value, avg_value # 返回的时元组
# 使用方式1:调用函数时,将光标放在函数名字上,就会有说明信息
get_list_result()
# 使用方式2:调用help函数,打印函数说明书
help(get_list_result)
总结:
(1)为了更规范的给函数添加注释,通常会在定义函数的第1行做解释说明
(2)通俗地说,说明文档就是更规范地给函数添加多行注释,注释只能通过源码来查看,而文档说明可以在任何位置查看
三、函数的嵌套调用
1、嵌套调用及执行流程
函数的嵌套调用指的是:在一个函数中,调用了另一个函数。
嵌套调用语法:
python
def 函数1():
代码
...
def 函数2():
代码
# 调用函数1
函数1()
...
说明:
在函数2中,调用了函数1。
例如,一起来完成:
(1)先定义一个test()函数和func()函数;
(2)接着,在函数test()中,嵌套调用func()函数,并在外部调用test()函数;
(3)执行程序,观察效果;
(4)思考:嵌套调用的执行流程是怎样的呢?
python
# 1.定义func()
def func():
print("==========AA===============")
print("==========Nfunc()============")
print("==========BB===============")
# 2.定义test()、调用func()
def test():
print("*************11****************")
func()
print("**********M调用了test方法**************")
print("*************22****************")
# 3.调用test()
test() # 1ANBM2
# 说明流程
# 定义函数test1()
def test1():
print('这个是test1函数')
# 嵌套调用
def test2():
test1()
print('这个是test2函数')
# 调用函数test2
test2()
print('------------------------------------------')
def 数据采集():
print('数据采集中!')
def 数据预处理():
print('数据预处理中!')
def 数据分析():
print('数据分析中!')
def 数据导出():
print('数据导出中!')
def shufen():
数据采集()
数据预处理()
数据分析()
数据导出()
# 调用函数
shufen()
总结:
(1)嵌套调用指的是:一个函数中,调用了另一个函数;
(2)注意:函数的嵌套调用执行流程较为复杂,需要多观察执行结果。
2、嵌套调用的应用
使用函数的嵌套调用,我们可以把复杂问题分解成多个简单问题,这样便于解决问题。
比如,要求多个数的平均值。此时,我们就可以拆分为两个函数:
(a)函数A:用于求解多个数之和;
(b)函数B:调用函数A,获取多个数之和,接着,再使用和除以总个数,就能求解出平均值。
例如,一起来完成:
(1)要完成一个输出任意条横线的需求;
(2)定义函数1:用于输出一条横线;
(3)定义函数2:先循环N次,再调用函数1,可输出N条横线;
(4)执行程序,观察效果。
python
# 1.定义一条横线的函数
def print_one_line():
print("-"*40)
# 2.N条横线
def print_lines(n):
for i in range(n):
print_one_line()
print_lines(10)
总结:采用函数的嵌套调用,可以让复杂问题简单化。
四、变量的作用域
1、局部变量
先来了解一下作用域的概念!
作用域指的是:内容生效的具体范围。
当根据作用域的不同,可以给变量分为两类:
(1)局部变量
(2)全局变量
局部变量指的是:定义在函数内部的变量或参数,且只在函数中生效。
局部变量语法:
python
def 函数名(参数1,参数2,...):
代码
变量名 = 值
...
说明:局部变量只作用在函数中。
例如,一起来完成:
(1)定义一个函数1,有局部变量:参数;
(2)定义一个函数2,有局部变量:变量;
(3)调用函数,观察程序执行效果。
python
print('--------局部变量-方法内部-----------')
# 定义在函数内部的变量称为局部变量,对外不可见
def func(a):
b = 20 # 局部变量
a = a +1 # 局部变量
print('a=',a)
print('b=',b)
# print(a) # 报错
# print(b) # 报错
func(10)
print('--------特殊情况-for内部-----------')
for i in range(10):
print(i)
print('i=',i) # for结束之后,这里的i可以访问,值为9
总结:
(1)局部变量只作用于局部作用域内。
(2)通常地,根据变量作用域的不同,可以把变量分为:局部变量、全局变量。
2、全局变量
全局变量指的是:在函数体内、外都能生效的变量。
通俗地说,与模块中定义的函数,处于同一级别的变量,就是全局变量。
全局变量语法:
python
变量名 = 值
def 函数名():
代码
...
# 变量名 = 值
说明:
(1)全局变量是指与函数处于同一级别的变量;
(2)注意:当函数中的局部变量与全局变量同名时,在函数中使用的是局部变量的值。
需要注意的是,当要修改全局变量的值时,记得提前使用global进行声明。
global关键字语法:
python
# 声明
global 变量名
# 修改值
变量名 = 修改后的值
例如,一起来完成:
(1)定义一个全局变量1,并在函数内外都使用;
(2)定义一个同名的全局变量2和局部变量,并在函数内使用该同名变量;
(3)执行程序,观察效果。
python
print('--------全局变量-----------')
# 定义在函数内部的变量称为局部变量,对外不可见
a = 10 # 全局变量
def func():
print(a) # 函数内部访问全局变量
print(a) # 函数外部访问全局变量
func()
print('--------全局变量-----------')
a = 10 # 全局变量
def test1():
a = 20 # 局部变量,是一个新的变量,不是对全局的a进行赋值
print('函数内部:a=', a) # 20
print('函数外部:a=', a) # 10
test1()
print('--------全局变量-global-----------')
a = 10 # 全局变量
# 如果你希望在函数的内部去修改全部变量的值,则需要使用global
def test1():
global a # 告诉解释器,这里的a是全局变量
a = 20 # 我希望这里不是局部变量,而是对全局变量重新赋值
print('函数内部:a=', a) # 20
test1() # 先调用,才会修改全部变量
print('函数外部:a=', a) # 20
总结:
(1)当要定义一个作用在整个模块的变量时,就可以使用全局变量;
(2)注意:当要在函数内部给全局变量修改值时,需要先使用global关键字来声明。
五、函数的多种参数
1、位置参数
位置参数指的是:调用函数时,根据函数定义的参数位置来传递数值。
位置参数语法:
python
def 函数名(参数1,参数2,...):
代码
...
函数名(值1,值2,...)
说明:
当调用函数时,要按照定义函数时的参数位置,进行传递值。
例如,一起来完成:
(1)定义一个使用格式化符号替换数据,且显示姓名、年龄的函数;
(2)调用函数,展示形成【个人名片】的样式。
python
print('-----------1、位置参数-------------------')
def show_infos(name, age):
print("========================")
print("显示个人信息如下:")
print("姓名:%s" % name)
print("年龄:%d" % age)
print("========================")
# 位置参数,实参会按照先后顺序依次的传递给形参
show_infos('刘备', 18)
总结:
(1)在给位置参数传递值时,要注意参数的位置、类型和顺序;
(2)注意:有时候采用位置参数传递值时,比较麻烦,就可以使用关键字参数。
2、关键字参数
关键字参数指的是:调用函数时,可以通过【键 = 值】的形式指定参数。
使用关键字参数后,可以让函数更加清晰、容易使用,同时也简化了传递参数的要求,比如不需要关注参数的个数、类型和顺序。
关键字参数语法:
python
def 函数名(参数1,参数2,...):
代码
...
函数名(参数1=值, 参数2=值,...)
说明:调用函数时,参数名必须要与定义函数时的名称保持一致。
例如,一起来完成:
(1)定义一个函数,用于显示个人名片的姓名、年龄、性别等信息;
(2)当调用函数时,使用关键字参数的形式传递值。
python
print('-----------2、关键字参数-------------------')
# 1.定义显示个人信息的函数
def show_infos(name, age, sex):
print("个人信息如下:")
print(f"姓名:{name}")
print(f"年龄:{age}")
print(f"性别:{sex}")
show_infos('刘备', 18, '男') # 位置传参,要考虑顺序
show_infos(name='刘备', age=18, sex='男') # 关键字传参,不用考虑参数顺序
show_infos(sex='男', age=18, name='刘备') # 关键字传参,不用考虑参数顺序
show_infos(sex='男') # 报错,必须给所有参数赋值
总结:
(1)当传递关键字参数时,可以使用【键 = 值】形式来指定参数;
(2)请问:当采用关键字参数传递值时,可以不关注参数的顺序,这句话正确吗?==A、正确==;B、错误。
3、缺省参数
有时候,缺省参数也叫默认参数。
缺省参数是指:在定义函数时,就为参数提供默认值。
与此同时,在调用函数时,就可以不用传递默认参数的值。当然了,如果给缺省参数传递了数值,则以传递的值为准。
缺省参数语法:
python
def 函数名(参数1,参数2,...,参数n=值):
代码
...
函数名(值1,值2,...[值n])
说明:缺省参数需要定义在最末尾。
例如,一起来完成:
(1)定义一个显示姓名、年龄、性别的函数,且默认性别为男;
(2)调用函数,观察程序执行结果;
(3)思考1:可以定义多个缺省参数吗?
(4)思考2:能否把缺省参数放在前面呢?
python
print('-----------3、缺省(默认)参数-------------------')
# 默认参数只能放在参数列表的最右边,有默认值的参数,可以传值,也可以不传入值
# 1.定义显示个人信息的函数
def show_infos(name, age, sex='男'):
print("个人信息如下:")
print(f"姓名:{name}")
print(f"年龄:{age}")
print(f"性别:{sex}")
show_infos('刘备', 18) # 位置传参,有默认值的可以不用传入
show_infos('小乔', 18, '女') # 位置传参,覆盖默认值
show_infos(name='刘备', age=18) # 关键字传参,有默认值的可以不用传入
print('-----------3、缺省(默认)参数2-------------------')
# 1.定义显示个人信息的函数
def show_infos(name, age=18, sex='男'):
print("个人信息如下:")
print(f"姓名:{name}")
print(f"年龄:{age}")
print(f"性别:{sex}")
show_infos('小乔')
show_infos('小乔', 17)
show_infos('小乔', 17,'女')
总结:
(1)若给函数定义了缺省参数,则在调用函数时可以省略该参数值的传递;
(2)缺省参数必须定义在其他参数的最末尾处,这句话正确吗?==A、正确==;B、错误。
4、不定长参数
有时候,不定长参数也叫可变参数。
通常情况下,不定长参数用于在不确定调用函数时,要传递多少个参数的场景,当然也可以不传递参数。
而当要调用函数时,可以给*args传递位置参数,给**kwargs传递关键字参数,这样显得更加方便。
不定长参数语法:
python
def 函数名(参数1,..,*args,**kwargs):
代码
...
函数名(值1, 值2, 值3, ... 参数1=值, 参数2=值,...)
例如,一起来完成:
(1)定义函数1,使用不定长参数*args求多个数之和;
(2)定义函数2,使用不定长参数**kwargs求多个数之和;
(3)综合两个函数,合并在一起完成求多个数之和;
(4)执行程序,观察效果。
python
print('-----------1、*args-------------------')
# 该函数是一个变参函数,传入参数必须使用位置传参
def my_sum(*args): # 将传入的多个参数封装到元组中 args = (1,2,3)
print(type(args)) # 元组
return sum(args)
print(my_sum()) # 0
print(my_sum(1)) # 1
print(my_sum(1, 2)) # 3
print(my_sum(1, 2, 3)) # 6
# --------------------------------------
def my_sum(num1, *args): # 将传入的多个参数封装到元组中 args = (1,2,3)
return sum(args)
print(my_sum(1)) # 1 -> 1给了num1 ,args没有值
print(my_sum(1, 2)) # 2 -> 1给了num1, 2给了args
print(my_sum(1, 2, 3)) # 5 -> 1给了num1, 2和3给了args
print('-----------2、**kwargs-------------------')
# 该函数是一个变参函数,传入参数必须使用关键字传参
def my_sum(**kwargs): # 将传入的多个参数封装到字典中
print(type(kwargs)) # 字典类型:<class 'dict'>
print(kwargs) # {'num1': 1, 'num2': 2, 'num3': 3}
my_sum(num1=1, num2=2, num3=3)
# ------------------------------------------
def my_sum(num, **kwargs): # 将传入的多个参数封装到字典中
print(type(kwargs)) # 字典类型:<class 'dict'>
print(kwargs) # {'num1': 1, 'num2': 2, 'num3': 3}
my_sum(888, num1=1, num2=2, num3=3) # 888 给了num,剩下的给kwargs参数
my_sum(num=888, num1=1, num2=2, num3=3) # 888 给了num,剩下的给kwargs参数
# my_sum(888,1, 2, 3) # 报错,不能使用位置传参
# ------------------------------------------
def my_sum(*args, sep='#'): # 将传入的多个参数封装到字典中
print(args)
print(sep)
my_sum(1, 2, 3, sep='$') # 1 2 3 给了 args, sep必须使用关键字传参
总结:
当给不定长参数传递数值时,可以理解为:就是综合运用位置参数和关键字参数来传值。
六、拆包和交换变量值
1、拆包
先来看看在现实生活中的拆包。比如,张同学背着背包来办公室上班后,需要从背包中拿出电脑、鼠标、数据线、电源线等,这个过程就是拆包!
接着,看一下在Python程序中的拆包:把组合形成的元组形式的数据,拆分出单个元素内容。
变量名1,变量名2,... = 结果
例如,一起来完成:
(1)在一个函数中,使用return返回求解最大值,最小值,平均值
(2)分别使用拆包方式来拆分数据。
python
# 需求:定义一个函数,传入一个数字列表,返回列表的最大值,最小值,平均值
# 1、定义函数
def get_list_result(list_name):
max_value = max(list_name)
min_value = min(list_name)
avg_value = sum(list_name) / len(list_name)
return max_value, min_value, avg_value # 返回的时元组
list1 = [1,2,3,4,5]
# 如果一个函数返回多个值,则可以使用多个变量来接受,被称为拆包
max_value,min_value,avg_value = get_list_result(list1)
print(max_value)
print(min_value)
print(avg_value)
总结:
(1)当要把一个组合的结果快速获取元素数据时,可以使用拆包来完成;
(2)注意:对列表、元组数据结果,都可以使用拆包方式。
2、交换变量值
使用拆包方式可以用于交换变量的值。
例如,一起来完成:
(1)有变量a、b,请完成变量之间值的交换;
(2)使用引入第三方变量的形式完成数值的交换;
(3)使用拆包方式完成数值交换。
python
print('-----------交换两个数的值:方式1-----------')
a = 10
b = 20
c = a
a = b
b = c
print(f'a = {a}')
print(f'b = {b}')
print('--------交换两个数的值:方式2-------------')
a = 10
b = 20
a,b = b,a
print(f'a = {a}')
print(f'b = {b}')
总结:
交换两个变量的方式较多,但最简单的是:直接使用拆包方式交换值。
七、引用
1、了解引用
引用可以通俗的称为内存地址值。在Python中,引用有两种表现形式:
(1)十进制数 5040624
(2)十六进制数 0x45AC6
注意:在Python中,变量值是通过引用来传递的。
查看引用语法:
id(变量名)
说明:我们可以把id()值理解为变量所在内存的地址值。
例如,一起来完成:
(1)定义一个变量a,查看变量的引用值;
(2)思考:有两个列表变量[1, 2],分别使用==和is去比较,结果如何?
python
# 引用
a = 10
b = 10
# 获取a存放的地址,也就是10这个数存放的内存地址
print(id(a)) # 140735745131056
print(id(b)) # 140735745131056
a = 20
print(id(a)) # 140735719572336
print('---------列表:可变,地址不同---------------')
list1 = [1,2,3]
list2 = [1,2,3]
print(id(list1)) #2301155693064
print(id(list2)) #2301155693576
print(list1 is list2 ) # 判断list1的地址和list2的地址是否相同
print('---------元组:不可变,地址相同---------------')
tuple1 = (1,2,3)
tuple2 = (1,2,3)
print(id(tuple1)) #1919263510840
print(id(tuple2)) #1919263510840
print(tuple1 is tuple2 ) # 判断tuple1的地址和tuple2的地址是否相同
print('---------字符串:不可变,地址相同---------------')
str1 = 'hello'
str2 = 'hello'
print(id(str1)) # 2087414306736
print(id(str2)) # 2087414306736
print(str1 is str2 ) # 判断str1的地址和str2的地址是否相同
总结:
对于可变类型,即使内容相同,地址值不同,对于不可变类型,内容相同,地址值也相同
注意:
比较两个变量的值是否相等时,使用==;比较两个变量的内存地址值是否相同时,使用is关键字。
2、把引用当做参数传递
我们知道,当定义函数时设定了参数,则在调用函数时也需要传递参数值。
而实际上,当给函数传递参数时,其本质就是:把引用当做参数进行传递。
例如,一起来完成:
(1)定义有一个参数的函数,并在调用函数时传递一个参数值;
(2)同时输出参数值与在函数内的参数的引用值,对比效果。
python
def func(b): # 实参a将地址传递给了形参b,a和b都指向同一片空间,也就是10存放的空间
print(id(b)) # 140735748014640
print(f'b={b}')
a = 10
print(id(a)) # 140735748014640
func(a) # 引用传递,传入的是地址值
总结:
当把变量传递给函数时,本质上是:传递变量的引用值。
八、匿名函数
1、lambda语法
定义匿名函数需要使用lambda关键字,可以创建小型匿名函数。
匿名函数表示没有名字的函数,这种函数得名于省略了用def关键字声明函数的标准步骤。
定义匿名函数语法:
lambda 参数列表 : 表达式
调用匿名函数语法:
函数名 = lambda 参数列表 : 表达式
函数名([参数列表])
例如,一起来完成:
(1)求解两个数之和;
(2)使用def定义函数,完成求和操作;
(3)使用匿名函数简化函数求和操作。
python
# 1、普通函数:求两个数的和
def add(num1, num2):
return num1 + num2
print(add(10, 20))
# 2、匿名函数:求两个数的和
# lambda 参数列表 : 表达式
# num1, num2表示匿名函数的参数, num1 + num2 表示函数的返回值
add2 = lambda num1, num2: num1 + num2 # add2其实是函数的名字
print(add2(10, 20))
总结:
当且仅当只需要调用使用一次时,可以优先使用匿名函数来完成。
注意:
匿名函数在实际应用中使用较少,了解即可。
2、lambda的应用
在实际应用中,为便于简化函数传递处理,我们可以使用lambda表达式作为参数进行传递,但要注意:传递的是一个引用。
在Python中,匿名函数通常使用lambda
表达式来创建。但是,需要注意的是,lambda
表达式仅用于编写单行的、简单的函数体。如果需要多条语句的函数体,应该使用def
关键字来定义一个常规的函数,而不是使用lambda
。
再来看一下匿名函数的语法。
定义语法:
lambda 参数列表 : 表达式
调用语法:
函数名 = lambda 参数列表 : 表达式
函数名([参数列表])
例如,一起来完成:
(1)把lambda表达式当作参数传递给函数;
(2)求解两个数之和,注意:在函数中定义变量并传递。
python
# 1.定义函数
def get_sum(func): # func = lambda a,b:a+b
x = 100
y = 998
print(f"求和:{func(x,y)}")
print('-----------将匿名函数作为参数传递----------------------')
# 2.调用 -传递匿名函数过去
# 可以把引用当作参数直接传递 -闭包
get_sum(lambda a,b:a+b) # lambda的匿名函数,只能是单行,而且这个单行就是函数的返回值
print('-----------将有名函数作为参数传递----------------------')
def add(a,b):
return a + b
get_sum(add)
总结:
(1)当要定义一个匿名函数时,需要使用lambda关键字
(2)当完成一个功能简单的需求时,可以使用匿名函数,而当需求较复杂时,不建议使用匿名函数。
【思考】使用函数形式来求解某天是该年的第几天?比如,2023年3月5日是2023年的第64天。
提示:要区分闰年、平年,闰年指的是能被4整除且不能被100整除,或者能被400整除的年份。
python
print('----------------------方式1--------------------------')
# 1.定义函数: 求是否是闰年
def is_run_year(year):
"""
判断是否是闰年
:param year: 年份
:return: 是闰年 True; 不是闰年: False
"""
if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0):
return True
return False
# 2.求解第几天: 之前月份的总天数+当前日期
def get_days(year, month, day):
days = 0
# 判断年份
# if is_run_year(year):
if is_run_year(year) == True:
day_lists = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30]
else:
day_lists = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30]
# 通过月份数求解之前月份的总天数
temp_ret = 0
i = 0
while i < month:
temp_ret += day_lists[i]
i += 1
# +当前日期
days = temp_ret + day
return days
# 3.输入年月日、调用函数
in_year = int(input("请输入年份:"))
in_month = int(input("请输入月份:"))
in_day = int(input("请输入日期:"))
print(f"{in_year}年{in_month}月{in_day}日是{in_year}年的第{get_days(in_year,in_month,in_day)}天.")
print('----------------------方式2--------------------------')
def is_leap_year(year):
"""
判断是否是闰年
:param year: 年份
:return: 是闰年返回 True; 不是闰年返回 False
"""
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def get_day_of_year(year, month, day):
"""
计算某天是该年的第几天
:param year: 年份
:param month: 月份
:param day: 日期
:return: 某天是该年的第几天
"""
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if is_leap_year(year):
days_in_month[1] = 29 # 如果是闰年,二月份有29天
days = sum(days_in_month[:month - 1]) + day # 累加前几个月的天数,并加上当前月的天数
return days
# 示例
print(get_day_of_year(2023, 3, 5)) # 输出应该是 64