零、文章目录
Python基础05-函数
1、函数的作用及其使用步骤
(1)函数的作用
-
在Python实际开发中,我们使用函数的目的只有一个“让我们的代码可以被重复使用”
-
函数的作用有两个:
-
① 代码重用(代码重复使用)==
-
② 模块化编程(模块化编程的核心就是函数,一般是把一个系统分解为若干个功能,每个功能就是一个函数)
-
(2)函数是什么
-
函数是一个被命名的、独立的、完成特定功能的代码段,其可能给调用它的程序一个返回值。
-
被命名的:在Python中,大部分函数都是有名函数(函数都有名字)
-
独立的、完成特定功能的代码段:函数的功能要专一,专门为了完成某个功能而定义
-
返回值:当函数执行完毕后,其可能会返回一个值给函数的调用处
-
(3)函数的定义
- 函数的定义:
def 函数名称([参数1, 参数2, ...]):函数体...[return 返回值]
(4)函数的调用
- 不同的需求,参数可有可无。
- 在Python中,函数必须先定义后使用。
# 定义函数
def 函数名称([参数1, 参数2, ...]):函数体...[return 返回值]# 调用函数
函数名称(参数1, 参数2, ...)
'''
Python中的函数是一个被命名的、独立的、完成特定功能的"一段代码",并"可能"给调用它的程序一个return返回值。
作用:① 代码重用 ② 模块化编程(把一个系统分解为若干个功能,每个功能就是一个函数)=> 面向过程
函数定义的基本语法:
def 函数名称([参数]):函数体代码(不仅一行,一般是一个完整的功能)[return 返回值]注意:① 函数的参数与返回值非必选项,可有可无,要根据业务的需要!② 在函数定义时,只是向内存中抛出一个函数的名称,其函数体内部的代码并没有真正执行,只有调用时,函数内部的代码才真正被执行!函数的调用过程:
函数名称() 找到内存中的函数名称,并立即执行其内部的代码!
'''
# 封装一个函数
def greet(name):return '您好,' + name# 见到张老师
result1 = greet('老张')
result1 += ',早上好,吃了么?'
print(result1)# 见到李老师
result2 = greet('老李')
print(result2)# 见到王老师
result3 = greet('老王')
print(result3)
(5)引入函数
① 使用Python代码,编写一个打招呼程序
第一步:见到一个老师,打一声招呼
print('您好')
第二步:见到一个老师,打一声招呼
print('您好')
第二步:见到一个老师,打一声招呼
print('您好')
虽然以上程序可以满足程序的需求,但是我们发现,我们的代码做了很多重复性的工作。我们能不能对以上代码进行进一步的优化,避免代码的重复性编写。
② 升级:使用Python代码,编写一个打招呼程序(函数——一次编写,多次利用)
# 定义函数(封装函数)
def greet():print('您好')# 调用函数
# 见到一个老师,打一声招呼
greet()
# 见到一个老师,打一声招呼
greet()
# 见到一个老师,打一声招呼
greet()
③ 升级:使用Python代码编写一个打招呼程序,可以实现向不同的人打不同的招呼
# 定义一个函数,同时为其定义一个参数
def greet(name):print(f'{name},您好')# 调用函数
# 见到了张老师,打一声招呼
greet('老张')
# 见到了李老师,打一声招呼
greet('老李')
# 见到了王老师,打一声招呼
greet('老王')
④ 升级:函数的设计原则“高内聚、低耦合”,函数执行完毕后,应该主动把数返回给调用处,而不应该都交由print()等函数直接输出。
# 定义一个函数,拥有name参数,同时函数执行完毕后,拥有一个return返回值
def greet(name):# 执行一系列相关操作return name + ',您好'# 调用函数
# 见到了张老师,打一声招呼
print(greet('老张'))
# 见到了李老师,打一声招呼
print(greet('老李'))
# 见到了王老师,打一声招呼
print(greet('老王'))
(6)函数返回值
-
如果一个函数如些两个return (如下所示),程序如何执行?
- 答:只执行了第一个return,原因是因为return可以退出当前函数,导致return下方的代码不执行。
-
思考:如果一个函数要有多个返回值,该如何书写代码?
- 答:可以一个return返回多个返回值,用逗号隔开,或者返回列表,集合或元组。
- 注意:①
return a, b
写法,返回多个数据的时候,默认是元组类型。② return后面可以连接列表、元组或字典,以返回多个值
'''
在函数的内部,当函数执行完毕后,可能会给函数调用的位置一个返回值,接下来聊聊返回值的概念
① 一个函数中是否可以同时拥有多个return,是否全部会被执行
答:从语法上,一个函数内部是可以同时拥有多个return关键字的,但是只有第一个return会被执行。因为函数一旦遇到了
return返回值,会立即执行两个操作:返回return后面的结果,强制中止此函数的继续执行。② 在其他编程语言中,一个函数只能返回一个值,那Python中的函数是否可以同时返回多个值呢?
答:在Python语言中,函数既可以返回一个值,也可以返回多个值(注意:多个值的返回,是以元组形式进行返回输出的)③ 当函数执行完毕后,return返回值到底返回到哪里了,如果一个函数要是没有返回值,则默认返回什么?
答:返回给函数调用位置,如果一个函数没有return返回值,则当这个函数执行完毕后,其返回None!
'''
# 1、定义一个func1()函数
def func1():return 1 # 多个return,返回第一个,后面代码不执行return 2return 3 result1 = func1()
print(result1) # 1 # 2、定义一个func2函数
def func2():return 1, 2, 3 # 多个返回值result2 = func2()
print(result2) # (1, 2, 3)
print(type(result2)) # <class 'tuple'># 3、定义一个func3()函数
def func3():pass # 无返回值result3 = func3()
print(result3) # None
2、函数的说明文档
(1)函数的说明文档是什么
- 思考:定义一个函数后,程序员如何书写程序能够快速提示这个函数的作用?
- 答:注释
- 思考:如果代码多,我们是不是需要在很多代码中找到这个函数定义的位置才能看到注释?如果想更方便的查看函数的作用怎么办?
- 答:函数的说明文档(函数的说明文档也叫函数的文档说明)。
(2)函数的说明文档的定义
- 定义函数的说明文档
def 函数名(参数):""" 说明文档的位置 """ 代码......
- 查看函数的说明文档,或者Ctrl + Q快速查看
help(函数名)
- 案例演示:
'''
函数说明文档:就相当于函数的说明书,在这个说明书中我们需要标注这个函数的作用、拥有的参数以及最终的返回值!
基本语法:
def func():""" 函数说明文档 """函数体代码如何快速查看函数的说明文档呢?
help(函数名称)
可以基于PyCharm中快捷键 => Ctrl + Q
'''
def sum_num(num1, num2):'''sum_num函数主要用于实现对两个数进行求和操作:param num1: int,代表第一个参数:param num2: int,代表第二个参数:return: 返回num1与num2的加和'''result = num1 + num2return result# 使用help方法就可以查看sum_num函数说明文档
help(sum_num)# 使用快捷键快速查看某个函数说明文档 => Ctrl + Q
sum_num()# 扩展一下:在Python中,所有的系统函数都有说明文档,如果遇到某个函数没有见过,直接使用Ctrl + Q就可以快速查看此函数说明文档
list1 = [1, 2, 3, 4, 5]
list1.reverse()
3、函数的嵌套
(1)函数的嵌套是什么
- 所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。
'''
所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。
学习重点:① 函数嵌套的基本语法② 掌握函数嵌套的执行流程
'''
# 1、定义一个testB函数
def testB():print('----- testB start -----')print('testB函数体代码...')print('----- testB end -----')# 2、定义testA函数
def testA():print('----- testA start -----')# 所谓的嵌套就是在一个函数的内部又调用了另外一个函数testB()print('----- testA end -----')# 3、执行testA函数
testA()
- 执行效果
----- testA start -----
----- testB start -----
testB函数体代码...
----- testB end -----
----- testA end -----
(2)执行过程
- 如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置。
(3)PyCharm调试小技巧
- 先打断点,然后Debug运行程序,执行至断点处。
- Step over(F8):代码一步一步向下执行,但是遇到了函数以后,不进入函数体内部,直接返回函数的最终的执行结果。
- Step into(F7):代码一步一步向下执行,但是遇到了函数以后,进入到函数体内部,一步一步向下执行,直到函数体的代码全部执行完毕。
4、函数的应用案例
(1)案例1
- 封装一个函数,求三个数的平均值
'''
案例:封装一个函数,求三个数的平均值
'''
# 1、定义一个函数
def func(num1, num2, num3):'''func函数主要用于求三个数的平均值:param num1: int, 第一个参数:param num2: int, 第二个参数:param num3: int, 第三个参数:return: 函数的返回值,返回三个数的平均值'''result = (num1 + num2 + num3) / 3return result# 2、调用函数
print(func(10, 20, 30))
(2)案例2
- 编写一个函数,有一个参数str1,输入信息如‘1.2.3.4.5’,使用函数对其进行处理,要求最终的返回结果为’5-4-3-2-1’
'''
案例:编写一个函数,有一个参数str1,输入信息如‘1.2.3.4.5’,使用函数对其进行处理,要求最终的返回结果为'5-4-3-2-1'
'''
# 1、定义一个函数
def func(str1): # str1 = '1.2.3.4.5'# ① 翻转 => 5.4.3.2.1str2 = str1[::-1]# ② 把点号替换为-横岗return str2.replace('.', '-')# 2、调用函数
print(func('1.2.3.4.5'))
(3)案例3
- 使用函数生成4位长度的验证码
'''
案例:使用函数生成4位长度的验证码
验证码可以起到防止恶意攻击(用户登录的时候只有账号和密码) => 账号和密码都是字符串,一般就是键盘上的相关字符组合
admin
123456
admin888
有很多暴力破解器 => 不断的进行字符串组合,然后尝试破解你的账号和密码!所以引入了一个随机验证码这样一个模块!
每次运行,生成的验证码都是不同的,所以暴力破解器,没办法识别每次的验证码,所以可以起到防止恶意攻击目的!
'''
# 第四步:引入random随机模块
import random
# 1、封装一个函数,生成4位长度的随机验证码
def func():# 第一步:定义一个字符串,用于生成验证码str1 = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'# 第二步:定义一个空字符串,专门用于接收4位长度的验证码code = ''# 第三步:生成4位长度的验证码其实就是循环4次,每次循环时要做两件事# 第一件事:从str1中随机获取一个字符# 第二件事:把获取到的随机字符,追加到code空字符串中for i in range(4):# 第五步:如何从str1中抽取一个随机字符?答:使用索引随机randnum = random.randint(0, len(str1) - 1)# 第六步:把每次得到的随机字符拼接到code变量中code += str1[randnum]# 第七步:把得到的结果作为函数的返回值return code# 2、调用func函数
print(func())
(4)案例4
- 使用函数生成指定长度的验证码
'''
案例:使用函数生成指定长度的验证码
验证码可以起到防止恶意攻击(用户登录的时候只有账号和密码) => 账号和密码都是字符串,一般就是键盘上的相关字符组合
admin
123456
admin888
有很多暴力破解器 => 不断的进行字符串组合,然后尝试破解你的账号和密码!所以引入了一个随机验证码这样一个模块!
每次运行,生成的验证码都是不同的,所以暴力破解器,没办法识别每次的验证码,所以可以起到防止恶意攻击目的!
'''
# 第四步:引入random随机模块
import random
# 1、封装一个函数,生成指定长度的随机验证码
def func(length):# 第一步:定义一个字符串,用于生成验证码str1 = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'# 第二步:定义一个空字符串,专门用于接收4位长度的验证码code = ''# 第三步:生成4位长度的验证码其实就是循环4次,每次循环时要做两件事# 第一件事:从str1中随机获取一个字符# 第二件事:把获取到的随机字符,追加到code空字符串中for i in range(length):# 第五步:如何从str1中抽取一个随机字符?答:使用索引随机randnum = random.randint(0, len(str1) - 1)# 第六步:把每次得到的随机字符拼接到code变量中code += str1[randnum]# 第七步:把得到的结果作为函数的返回值return code# 2、调用func函数
print(func(6))
5、变量的作用域
(1)变量的作用域是什么
-
变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用),主要分为两类:全局作用域与局部作用域。
-
在函数内部定义范围就称之为局部作用域,在函数外部(全局)定义范围就是全局作用域
# 全局作用域
def func():# 局部作用域
(2)局部变量和全局变量
- 在Python中,定义在函数外部的变量就称之为全局变量;定义在函数内部变量就称之为局部变量。
# 定义在函数外部的变量(全局变量)
num = 10
# 定义一个函数
def func():# 函数体代码# 定义在函数内部的变量(局部变量)num = 100
(3)变量作用域的作用范围
- 全局变量:在整个程序范围内都可以直接使用
'''
在全局作用域中定义的变量就是全局变量!
探讨一下全局变量的访问范围:
① 在全局作用域中可以访问全局变量
② 全局变量还可以在局部作用域中访问
综上所述:全局变量既可以在全局作用域中访问,也可以在局部作用域中访问,其是通用的!
'''
str1 = 'hello'
# 定义一个函数
def func():# 在函数内部调用全局变量str1print(f'在局部作用域中调用str1变量:{str1}')# 直接调用全局变量str1
print(f'在全局作用域中调用str1变量:{str1}')
# 调用func函数
func()
- 局部变量:在函数的调用过程中,开始定义,函数运行过程中生效,函数执行完毕后,销毁。在全局作用域访问局部变量报错。
'''
局部变量:在局部作用域(函数的内部)中定义的变量就被称之为局部变量。
探讨一下局部变量访问范围:
① 局部变量是可以在局部作用域中访问的
② 局部变量是否可以在全局作用域中访问呢?答:不能,因为计算机的垃圾回收机制
综上所述:局部变量不是万能的,只能在局部作用域中访问,无法在全局作用域中访问,因为当函数执行完毕后,其局部变量会自动被计算机的内存所回收!扩展:内存的垃圾回收机制
因为函数执行完毕后,其内部的局部变量与程序都要被计算机的内存所回收!
早期计算机内存只有2MB,所以需要即用即清,所以的计算机程序,都需要先加载数据到内存,局部变量也会占用一段内存空间。
又由于局部变量一般只在函数调用时被使用,当函数调用结束,其变量就变得没有价值。所以计算机的内存会自动执行清理操作把局部变量占用的空间及时回收,所以会导致,在全局作用域中无法直接访问局部变量!
'''# 定义一个函数
def func():# 在函数内部定义一个局部变量num = 10print(f'在局部作用域中调用num局部变量:{num}')# 调用func函数
func()
# 在全局作用域中调用num局部变量
print(f'在全局作用域中调用num局部变量:{num}')
(4)global关键字
- 在局部作用域中是无法对全局变量进行修改的,一定要进行修改,必须使用global关键字。
# 定义全局变量num = 10
num = 10
# 定义一个函数func
def func():# 尝试在局部作用域中修改全局变量 修改失败num = 20# 调用函数func
func()
# 尝试访问全局变量num
print(num) # 10
- 加上global关键字,global关键字只是针对不可变数据类型的变量进行修改操作(数值、字符串、布尔类型、元组类型),可变类型可以不加global关键字。
# 定义全局变量num = 10
num = 10
# 定义一个函数func
def func():# 尝试在局部作用域中修改全局变量 加上global关键字,修改成功global numnum = 20# 调用函数func
func()
# 尝试访问全局变量num
print(num) # 20
6、函数参数进阶
(1)形参和实参
-
在函数定义与调用时,我们可以根据自己的需求来实现参数的传递。在Python中,函数的参数一共有两种形式:
- 形参:在函数定义时,所编写的参数就称之为形式参数
- 实参:在函数调用时,所传递的参数就称之为实际参数
'''
在Python代码中,函数定义时所指定的参数被称之为形式参数,简称(形参)函数调用时所指定的参数被称之为实际参数,简称(实参)
还要特别注意:函数的形参属于局部变量,只能在函数的内部使用
'''
def greet(name): # name是一个形参# name作用域只在此函数内部有效,因为其是一个局部变量return '您好,' + name# 定义一个全局变量
name = '老王'
greet(name) # 函数调用时所指定的参数是一个实参,通常是一个全局变量
(2)函数的参数类型
-
位置参数:调用函数时根据函数定义的参数位置来传递参数,传递和定义参数的顺序及个数必须一致。
-
关键字参数:函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
# 1、定义一个函数
def func(name, age, mobile):print(name)print(age)print(mobile)# 2、在函数调用时,函数一共有3个参数,所以调用时也需要传递3个参数,但是传递过程中有两种传递方式:① 位置传参 ② 关键词传参
# ① 位置传参,根据函数定义时参数的位置传递参数的值(强调参数的位置,顺序不能颠倒)
func('Tom', 23, '10086')# ② 关键词传参,根据"参数=值"方式来实现对参数的传递,优势:不需要考虑位置关系,只要参数名称没错,任何位置都可以
func(name='Jack', mobile='10010', age=19)
(3)缺省参数(默认值)
- 缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
- 函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值。
'''
在Python代码中,函数定义时的参数一共有3种类别:
① 普通参数,如def func(name, age, mobile)
② 缺省参数(默认值参数),如def func(name, age, gender='male')
③ 不定长参数,如def func(*args, **kwargs)
有些情况下,我们可以为某个参数定义一个默认值,我们把这种带有默认值的参数就称之为缺省参数(默认值参数)
基本语法:
def 函数名称(普通参数, 参数名称=默认值):pass# 优点:① 如果我们传参过程中,想让某个参数拥有默认值,可以直接省略参数的传递
函数名称(普通参数的值)② 如果你不想使用默认值,则可以给默认值参数传递一个值,用于替换默认值
'''
def student(name, age, gender='male'):print(name, age, gender)# 调用student函数
student('Tom', 23)
student('Jack', 25)
student('婉儿', 19, 'female')
(4)不定长参数
- 不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
- **不定长元组(位置)参数:**传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型。
def user_info(*args):print(args)user_info('TOM')# ('TOM',)
user_info('TOM', 18)# ('TOM', 18)
- **不定长字典(关键字)参数:**传进的所有参数都会被kwargs变量收集,它会根据传进参数的位置合并为一个字典(tuple),kwargs是字典类型。
def user_info(**kwargs):print(kwargs)user_info(name='TOM', age=18, id=110)# {'name': 'TOM', 'age': 18, 'id': 110}
'''
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
*args :不定长位置参数(不定长元组参数),*args代表固定格式,args代表变量的名称,主要用于接收不定长位置参数
**kwargs :不定长关键词参数(不定长字典参数),**kwargs代表固定格式,kwargs代表变量名称,主要用于接收不定长关键词参数
'''
# 定义func函数时,参数应该如何编写呢?
def func1(*args):print(args)# 调用一个函数时,可以有多重调用方法
func1()
func1(1)
func1(1, 2)
func1(1, 2, 3)
################################################
def func2(**kwargs):print(kwargs)func2()
func2(a=1)
func2(a=1, b=2)
func2(a=1, b=2, c=3)
- *args与**kwargs一起使用
'''
在实际Python开发工作中,*args与**kwargs还可以结合在一起使用!
注意事项:*args必须放在左边,**kwargs必须放在右边
'''
def func(*args, **kwargs):print(args)print(kwargs)# 当我们调用func函数时为其传递参数,*args用于接收位置参数,**kwargs用于接收关键词参数
func(1, 2, 3, a=4, b=5)# 输出
# (1, 2, 3)
# {'a': 4, 'b': 5}
# 需求:请封装一个函数,用于接收list1与dict1的值,然后对其进行求和操作,函数最终返回结果为1+2+3+4+5
# 在Python中,*args还可以专门用于接收列表类型或者元组类型的数据
# **kwargs还可以专门用于接收字典类型的数据
def func(*args, **kwargs):sum = 0for i in args:sum += ifor value in kwargs.values():sum += valueprint(sum)list1 = [1, 2, 3]
dict1 = {'a':4, 'b':5}func(*list1, **dict1)# 15
- 参数混用情况
'''
在Python代码中,函数定义时的参数一共有3种类别:
① 普通参数,如def func(name, age, mobile)
② 缺省参数(默认值参数),如def func(name, age, gender='male')
③ 不定长参数,如def func(*args, **kwargs)
在函数中,以上三种参数还可以混合在一起使用,特别注意:顺序很重要
def func(① 普通参数 ② *args ③ 缺省参数 ④ **kwargs):pass
'''
def func(a, b, *args, c=4, **kwargs):print(a, b)print(args)print(c)print(kwargs)# 如何传递参数
func(1, 2, 3, c=100, d=5, e=6)# 输出
# 1 2
# (3,)
# 100
# {'d': 5, 'e': 6}
7、引用变量及可变类型、非可变类型
(1)值传递与引用传递
- 在大多数编程语言中,值的传递通常可以分为两种形式“值传递与引用(地址)传递”,但是在Python中变量的传递基本上都是引用(地址)传递。
- 我们可以用id() 来判断两个变量是否为同一个值的引用。我们可以将id值理解为那块内存的地址标识。
(2)可变类型与不可变类型
-
可变类型:当这个内存地址一旦固定,其值还可以改变的数据类型
-
列表
-
字典
-
集合
-
-
不可变类型:当这个内存地址一旦固定,则其值无法改变的数据类型
- 整型
- 浮点型
- 字符串
- 元组
# 整数类型:不可变类型
a = 1
b = a
print(b) # 1
print(id(a)) # 140731559954872
print(id(b)) # 140731559954872
a = 2 # a的值发生改变
print(id(a)) # 140731559954904,a的地址变成了新地址
print(id(b)) # 140731559954872,b的地址没有变化
print(b) # 1, 不可变数据类型(数值)在赋值以后,其中一个值的改变相当于指向一个新的地址,不影响另外一个变量,因为两者指向空间地址不同。# 列表序列:可变数据类型
aa = [10, 20]
bb = aa
print(id(aa)) # 1661917188352
print(id(bb)) # 1661917188352
aa.append(30) # aa的值发生改变
print(id(aa)) # 1661917188352,aa地址没有发生改变
print(id(bb)) # 1661917188352,bb地址没有发生改变
print(bb) # [10, 20, 30], 可变数据类型(列表)在赋值以后,其中一个值的改变影响另外一个变量,因为两者指向空间地址相同。
(3)可变类型与不可变类型函数中应用
- 可变类型:在全局或局部中对可变类型进行增删改操作,其外部和内部都会受到影响。
# 定义一个函数
def func(names2):# names2 = names1# 局部作用域names2.append('赵六')# 定义一个全局变量
names1 = ['张三', '李四', '王五']
# 调用函数
func(names1)
print(names1) # A. ['张三', '李四', '王五'] B. ['张三', '李四', '王五', '赵六']
- 不可变类型:局部或全局的改变对外部和内部都没有任何影响。
# 定义一个函数
def func(num):# num = anum += 1print(num)# 定义一个全局变量
a = 10
# 调用函数
func(a)
# 在全局作用域中打印a
print(a) # 10
8、元组拆包
(1)拆包是什么
- 简单来说就是把一个元组中的数据一个一个拆解出来的过程,就称之为叫做拆包操作。
(2)基本语法
'''
什么是拆包?
简单来说就是把一个元组中的数据一个一个拆解出来的过程,就称之为叫做拆包操作。
注意:元组中有多少个元素,则左边的变量就有多少个
'''
tuple1 = (10, 20)
# 拆包
num1, num2 = tuple1# 以上代码可以简写为
num1, num2 = (10, 20)# 还可以进一步简写
num1, num2 = 10, 20print(num1)
print(num2)
(3)变量交换案例
'''
# 第一步:把c2 和 c1先组装为一个元组(c2, c1),圆括号可以省略不写(不写也是一个元组)
# 第二步:利用元组拆包特性,把c2的值赋值给c1变量,把c1的值赋值给c2变量
'''c1 = '可乐'
c2 = '牛奶'
c1, c2 = c2, c1
print(c1)# 牛奶
print(c2)# 可乐