global修饰符
当变量在函数内,这个变量是“局部变量”;
当变量在函数外,这个变量是“全局变量”。
1. 引例:尝试“跨函数”修改全局变量
a=10
def test1(a):#想要通过函数把a改成20
a+=20
test1(a) #执行修改函数
print(a)
#输出:10!修改失败
2. 为什么修改失败?
因为在本例中,把“全局变量”传给“形参”。
而方法体的运算操作,是对“形参”操作。
输出时,却输出的是“全局变量”
因为当结束调用函数时,函数内的变量自动销毁。
局部变量 只能在 函数内 访问和修改
3.解决方案:global修饰符
a=10
def test2():#global解决方案的函数
global a #使用global修饰符
a+=20
return a
print(test2())
#输出:30!修改成功
当使用global修饰符,解释器就在“局部变量块”中使用“全局变量”
4. global的bug:确保global变量的唯一性
def test1(b):
a=9999
global a
a+=20
return a
#SyntaxError:
#name 'a' is assigned to before global declaration
#global变量 不能和 局部变量 重复
def test1(a):
global a
a+=20
return a
#SyntaxError:
#name 'a' is parameter and global
#global变量 不能和 形参 重复
#global不能放for里
可变类型 / 不可变类型 の修改
可变类型:列表、字典、集合
不可变类型:数字、字符串、元组
这些类型都是对象。在Python中,对这些对象明确规定了:哪些可以修改、哪些不可以修改。这样就形成了可变类型和不可变类型。
引用 & 实际内存
在一条赋值语句中:a=1
,a是一个引用,1是实际的内存空间,a指向1。所有数据类型的赋值都是这样的内存示意。
可变类型:内存的共享
为什么说“列表、字典、集合”是可变类型?那是因为可变类型的内存是可共享的:可被多个引用(变量)指向。
list=[1,2,3,4,5]
def modify(l_ist):
l_ist+=[6,7]
print("我操控形参来修改,结果:",list)
li_st=list #让局部变量li_st指向list
li_st+=[8,9,10]
print("我操控局部变量来修改,结果",list)
modify(list)
print("最后我再输出下全局变量,结果",list)!
#我操控形参来修改,结果: [1, 2, 3, 4, 5, 6, 7]
#我操控局部变量来修改,结果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#最后我再输出下全局变量,结果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
全局变量list、形参l_ist、局部变量li_st虽然是不同(栈内存)的变量,但它们都指向实际的内存空间:[1,2,3,4,5]。
实际内存空间,都被三个指向(引用),所共享!
因此,对任意一个引用进行运算操作,都能改变实际的空间!
不可变类型:内存不能共享
a=10
def modify2(a):
a+=10
print(a)
所以a+=10仅仅是对形参的操作。
形参和全局变量是毫不相关的,所以互不影响。
可变类型修改的bug:修改无效
list=[1,3,5,7,9]
def modify3(list): #修改list
list=[2,4,6,8,10]
print(list) #修改无效
#输出:[1,3,5,7,9],修改失败
那是因为:
形参list 指向 [1,3,5,7,9]
局部变量list 指向 [2,4,6,8,10] (新的内存空间)
要注意 形参 和 局部变量 不是一个东西!他们虽然同名,但分别指向不同的内存空间!
怎样利用 局部变量 也能访问修改 全局list呢?(提示:用修改指向)
修改指向的思路是对的,但由于局部变量在函数结束调用被销毁,所以即使修改了指向,也是无效的。
总结
不可变类型 的 修改
- 因为内存不被共享(不能共享引用),不能在局部块中修改
只能用global修饰符修改
可变类型 的 修改
- 因为内存被共享(可共享多个引用),可以在任意地方修改
- 也可以通过global修饰符修改
递归
def jiec(i):
if i==1:
return 1
return i*jiec(i-1)
看懂递归代码的关键点:
1. 函数入口(层) 2.函数出口(返回值)
匿名函数
匿名函数是个函数,是没有名字的函数。
参数、返回值是一个函数的必需品。匿名函数把这两个必需品的语法格式进行了最大地简化。
sum=lambda a,b:a+b
'''
lambda:匿名函数声明标记
形参:用逗号间隔
返回值:前面加冒号
'''
匿名函数的应用
sort函数
stus=[
{"name":"zhangsan","age":22},
{"name": "lisi", "age": 21},
{"name": "wangwu", "age": 19}
]
stus.sort(key=lambda i:i["age"])
sort函数有一个参数:key。形参key是一个函数。
被sort()的集合的所有元素,都会执行key函数
key有什么作用?key就是指定针对什么进行排序。
我们想要针对age
排序,就要想办法把age的值赋值给key。这就用到了匿名函数
stus.sort(key=lambda i:i["age"])
#形参是i,是字典元素
#返回值是i["age"],是每个字典元素age键的值
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。