目录
一、变量进阶
1.1 变量和引用
>变量和数据都是保存在内存中的;在Python中函数的参数传递以及返回值都是靠引用传递的。
>在Python中,变量和数据是分开存储的,数据保存在内存中的一个位置,变量中保存这数据在内存中的地址,变量中记录数据的地址,就叫做引用。
>使用id()函数可以查看变量中保存数据所在的内存地址。如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用。
1.2 可变和不可变类型
>不可变类型
内存中的数据不允许被修改:
数字型int,bool,float,complex,long(2.x)
字符串str
元组tuple
>可变类型
内存中是的数据可以被修改
列表list
字典dict
>字典中的key只能使用不可变类型的数据
可变类型的数据变化,是通过方法来实现的; 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改。
>哈希(hash)
Python中内置有一个名字叫做hash()的函数,接收一个不可变类型的数据作为参数,返回结果是一个整数。
哈希是一种算法,其作用是提取数据的特征码,相同的内容得到相同的结果,不同的内容得到不同的结果。
在Python中,设置字典的键值对时,会首先对key进行hash已决定如何在内存中保存字典的数据,以方便后序对字典的操作:增、删、改、查。键值对的key必须是不可变类型数据;键值对的value可以是任意类型的数据。
1.3 局部变量和全局变量
>局部变量
局部变量是在函数内部定义的变量,只能在函数内部使用;函数执行结束后,函数内部的局部变量,会被系统回收;不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响。
作用:在函数内部使用,临时保存函数内部需要使用的数据。
局部变量的生命周期:
所谓生命周期就是变量从被创建到被系统回收的过程;局部变量在函数执行时才会被创建;
函数执行结束后局部变量被系统回收;局部变量在生命周期内,可以用来存储函数内部临时使用到的数据;
>全局变量
全局变量时在函数外部定义的变量(没有定义在某一个函数内),所有函数内部都可以使用这个变量。
函数执行时,需要处理变量时会:
1.首先查找函数内部是否存在指定名称的局部变量,如果有,直接用;
2.如果没有,查找函数外部是否存在指定名称的全局变量,如果有,直接使用
3.如果还没有,程序报错!
(1)函数不能直接修改全局变量的引用,在函数内部,可以通过全局变量的引用来获取对应的数据,但是不允许直接修改全局变量的引用。
(2)如果在函数中需要修改全局变量,需要使用global进行声明
(3)为了保证所有的函数都能够正确使用到全局变量,应该将全局变量定义在其它函数的上方。
(4)为了避免局部变量和全局变量出现混淆,在定义全局变量时,有些公司会有一些开发要,如全局变量名前应该增g_或gl_的前缀。
1.4 函数参数和返回值的作用
函数根据有没有参数以及有没有返回值可以相互组合。
无参数无返回值;无参数有返回值;有参数无返回值;有参数有返回值
如果函数内部处理的数据不确定,就可以将外界的数据以参数传递到函数内部;
如果希望一个函数执行完成后,向外界汇报执行结果,就可以增加函数的返回值;
1.5 多个返回值
def measure():
"""测量温度和湿度"""
print("测量开始。。。")
temp = 39
wetness = 50
print("测量结束。。。")
# 元组-可以包含多个数据,因此可以使用元组让函数一次返回多个值
# 如果函数返回的类型是元组,小括号可以省略
# return (temp,wetness)
return temp,wetness
# 元组
result = measure()
print(result)
# 需要单独的处理温度或者湿度--不方便
print(result[0])
print(result[1])
# 如果函数返回的类型是元组,同时希望单独地处理元组中的元素
# 可以使用多个变量,一次接收函数的返回结果
# 注意:使用多个变量接收结果时,变量的个数应该和元组中元素的个数保持一致
gl_temp,gl_wetness = measure()
print(gl_temp)
print(gl_wetness)
测量开始。。。
测量结束。。。
(39, 50)
39
50
测量开始。。。
测量结束。。。
39
50
1.6 交换两个数字
a = 6
b = 100
# 解法1:使用其他变量
# c = a
# a = b
# b = c
# 解法2:不使用其他变量
# a = a + b
# b = a - b
# a = a - b
# 解法3:Python专有
# a, b = (b, a)
# 提示:等号右边是一个元组,只是把小括号省略了
a, b = b, a
print(a)
print(b)
100
6
二、函数参数的进阶
2.1 不可变和可变的参数
>在函数内部,针对参数使用赋值语句,不会影响调用函数时传递的实参变量
>无论传递的参数是可变还是不可变的,只要针对参数使用赋值语句,会在函数内部修改局部变量的引用,不会影响到外部变量的引用。
>如果传递的参数是可变类型,在函数内部,使用方法修改了数据的内容,同样会影响到外部的数据。
def demo(num_list):
print("函数内部的代码")
# 使用方法修改列表的内容
num_list.append(9)
print(num_list)
print("函数执行完成")
gl_list = [1, 2, 3]
demo(gl_list)
print(gl_list)
函数内部的代码
[1, 2, 3, 9]
函数执行完成
[1, 2, 3, 9]
2.2 +=
>在Python中,列表变量调用+=本质上是在执行列表变量的extend方法,不会修改变量的引用
def demo(num, num_list):
print("函数开始")
# num = num + num
num += num
# 列表变量使用 + 不会做相加再赋值的操作!
# num_list = num_list + num_list
# 本质上是调用列表的extend方法
# num_list += num_list
# num_list.extend(num_list)
print(num)
print(num_list)
print("函数完成")
gl_num = 9
gl_list = [1, 2, 3]
demo(gl_num,gl_list)
print(gl_num)
print(gl_list)
函数开始
18
[1, 2, 3, 1, 2, 3]
函数完成
9
[1, 2, 3, 1, 2, 3]
2.3 缺省参数
>定义函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数
>调用函数时,如果没有传入缺省参数 的值,则在函数内部使用定义函数时指定的参数默认值
>函数的缺省参数,将常见的值设置为参数的缺省值,从而简化函数的调用
实例:对列表的排序
gl_list = [6, 3, 9]
# 默认按照升序排序
# gl_list.sort()
# 如果需要降序排序,需要执行reverse参数
gl_list.sort(reverse=True)
print(gl_list)
[9, 6, 3]
>指定函数的缺省参数
在参数使用后使用赋值语句,可以指定参数的缺省值。
>缺省函数的注意事项
必须保证带有默认值的缺省参数在参数列表末尾;在调用函数时,如果有多个缺省参数,需要指定参数名。
2.4 多值参数
定义支持多值参数的函数。参数名前增加一个*可以接收元组;参数名前增加两个**可以接收字典。
>一般在给多值参数命名时,习惯用*arg存放元组参数,**kwargs存放字典参数。
实例:多值参数,计算任意多个数字的和
需求
1.定义一个函数sum_numbers,可以接收到任意多个整数
2.要求:将传递的所有数字累加并且返回累加结果
def sum_number(*args):
# def sum_number(args):
num = 0
print(args)
for n in args:
num += n
return num
result = sum_number(1,2,3,4,5)
# result = sum_number((1,2,3,4,5))
print(result)
(1, 2, 3, 4, 5)
15
>元组和字典的拆包
在调用带有多值参数的函数时,如果希望将一个元组变量直接传递给args,将一个字典变量直接传递给kwargs,就可以使用拆包,简化参数的传递,拆包的方式是:
在元组变量前增加一个*,在字典变量前增加两个*。
def demo(*args, **kwargs):
print(args)
print(kwargs)
# 元组变量/字典变量
gl_nums = (1, 2, 3)
gl_dict = {"name":"小明","age":18}
# demo(gl_nums, gl_dict)
# 拆包语法,简化元组变量/字典变量的传递
demo(*gl_nums, **gl_dict)
demo(1,2,3, name="小明", age=18)
(1, 2, 3)
{'name': '小明', 'age': 18}
(1, 2, 3)
{'name': '小明', 'age': 18}
三、函数的递归
3.1 特点
>特点:一个函数内部调用自己。
>代码特点:函数内部的代码是相同的,只是针对参数不同,处理的结果不同;
当参数满足一个条件时,函数不再执行。
实例:
def sum_number(num):
print(num)
# 递归的出口,当参数满足某个条件时,不再执行函数
if num == 1:
return
# 自己调用自己
sum_number(num - 1)
sum_number(3)
3
2
1
3.2 递归案例
计算数字累加。
需求:1.定义一个函数sum_numbers
2.能够接收一个num的整数参数
3.计算1+2+...num的结果
def sum_numbers(num):
# 1.出口
if num == 1:
return 1
# 2.数字的累加 num + (1....num-1)
# 假设 sum_numbers 能够正确的处理 1...num-1
temp = sum_numbers(num-1)
return num + temp
result = sum_numbers(100)
print(result)
5050