一、nolocal关键字
在之前的课程中,我们学过global关键字。
name = 'root'
def outer():
name = "张三"
def inner():
global name # 修改全局变量name为123
name = 123
inner()
print(name)
outer()
print(name) # 指向全局变量,但是全局变量已经被修改,所以此处name=123
其实,还有一个nolocal关键字,用的比较少,此处作为了解即可。主要是修改上级作用域的变量。
name = 'root'
def outer():
name = "张三"
def inner():
nonlocal name # 此处修改name 指向的是上一级作用域的name,即name = "张三"
name = 123
inner()
print(name) # 此处name为123
outer()
print(name) # 此处仍然指向全局,name为root
name = 'root'
def outer():
name = 'zhangsan'
def func():
name = "张三" # 被下方的nonlocal修改name为123
def inner():
nonlocal name # 修改上一级变量name为123
name = 123
inner()
print(name) # 123
func()
print(name) # zhangsan
outer()
print(name) # root
name = 'root'
def outer():
name = '李四' # 被nonlocal ,name为张三,又被nonlocal 为123
def func():
nonlocal name # 被nonlocal ,name为123
name = "张三"
def inner():
nonlocal name
name = 123
inner()
print(name) # 123
func()
print(name) # 123
outer()
print(name) # root
二、 yield from
在生成器部分我们了解了yield关键字,其在python3.3之后有引入了一个yield from。
def foo():
yield 2
yield 2
yield 2
def func():
yield 1
yield 1
yield 1
yield from foo()
yield 1
yield 1
for item in func():
print(item)
三、深浅拷贝(面试出现概率高)
- 深浅拷贝一般都是说的可变类型:set、list、dict(不可变类型在进行深浅拷贝时无意义-内部都不会去拷贝,永远是同一块内存地址)
import copy
v1 = "张三"
v2 = copy.copy(v1)
print(id(v1)) # 140663937558640
print(id(v2)) # 140663937558640
- 浅拷贝,只拷贝第一层的可变类型。
- 深拷贝,拷贝所有层的可变类型 + 元素中如果有可变类型,也会被拷贝。
# 浅拷贝,针对可变类型只拷贝第一层,内部不可变类型&可变类型都不会被拷贝。
import copy
v1 = ["张三", "root", [44, 55]]
v2 = copy.copy(v1)
print(id(v1)) # 140370940277440
print(id(v2)) # 140370940279744 v1与v2内存地址不同,此处拷贝的列表本身,而不是列表里边的数据,列表本身存储地址不同,被成功拷贝
print(id(v1[2])) # 140364497610864
print(id(v2[2])) # 140364497610864 但是v1的第2个元素和v2的第2个元素位置相同,可变类型没有被拷贝
# 深拷贝,对于可变类型无论在那一层都会被拷贝,不可变类型永远不会被拷贝。
import copy
v1 = ["张三", "root", [44, 55]]
v2 = copy.deepcopy(v1)
print(id(v1)) # 140541799775168
print(id(v2)) # 140541799773120 最外层成功拷贝
print(id(v1[0])) # 140687559878768 但是内部的不可变类型,内层地址一样,没有被拷贝
print(id(v2[0])) # 140687559878768
print(id(v1[2])) # 140526364734720 可变类型被拷贝
print(id(v2[2])) # 140526364882368
# 特殊的:元组,不可变类型如果遇到
# - 浅拷贝,永远不会拷贝。
# - 深拷贝,当元素的元素中都是不可变类型时,永远不会拷贝;如果元素中有可变类型,也会被拷贝
import copy
v1 = (11, 22, [11, 22], 33)
v2 = copy.deepcopy(v1)
print(id(v1)) # 2774135044032
print(id(v2)) # 2774135044112
1.浅拷贝
【1】不可变类型,不拷贝
import copy
v1 = "张三"
print(id(v1)) # 140652260947312
v2 = copy.copy(v1)
print(id(v2)) # 140652260947312
按理说拷贝v1之后,v2的内存地址应该不同,但由于python内部优化机制,内存地址是相同的,因为对不可变类型而言,如果以后修改值,会重新创建一份数据,不会影响原数据,所以,不拷贝也无妨。
【2】可变类型,只拷贝第一层。
import copy
v1 = ["张三", "root", [44, 55]]
print(id(v1)) # 140405837216896
print(id(v1[2])) # 140405837214592
v2 = copy.copy(v1)
print(id(v2)) # 140405837214784
print(id(v2[2])) # 140405837214592
2. 深拷贝
【1】不可变类型,不拷贝
import copy
v1 = "张三"
print(id(v1)) # 140188538697072
v2 = copy.deepcopy(v1)
print(id(v2)) # 140188538697072
【2】特殊的元组:
- 元组元素中无可变类型,不拷贝
import copy
v1 = ("张三", "root")
print(id(v1)) # 140243298961984
v2 = copy.deepcopy(v1)
print(id(v2)) # 140243298961984
- 元素元素中有可变类型,找到所有【可变类型】或【含有可变类型的元组】 均拷贝一份
import copy
v1 = ("张三", "root", [11, [44, 55], (11, 22), (11, [], 22), 33])
v2 = copy.deepcopy(v1)
print(id(v1)) # 140391475456384
print(id(v2)) # 140391475456640
print(id(v1[2])) # 140352552779008
print(id(v2[2])) # 140352552920448
print(id(v1[2][1])) # 140642999940480
print(id(v2[2][1])) # 140643000088832
print(id(v1[2][2])) # 140467039914560
print(id(v2[2][2])) # 140467039914560
print(id(v1[2][3])) # 140675479841152
【3】可变类型,找到所有层级的 【可变类型】或【含有可变类型的元组】 均拷贝一份
import copy
v1 = ["张三", "root", [11, [44, 55], (11, 22), (11, [], 22), 33]]
v2 = copy.deepcopy(v1)
print(id(v1)) # 140391475456384
print(id(v2)) # 140391475456640
print(id(v1[2])) # 140352552779008
print(id(v2[2])) # 140352552920448
print(id(v1[2][1])) # 140642999940480
print(id(v2[2][1])) # 140643000088832
print(id(v1[2][2])) # 140467039914560
print(id(v2[2][2])) # 140467039914560
print(id(v1[2][3])) # 140675479841152
print(id(v2[2][3])) # 140675480454784
import copy
v1 = ["张三", "root", [44, 55]]
v2 = copy.deepcopy(v1)
print(id(v1)) # 140405837216896
print(id(v2)) # 140405837214784
print(id(v1[2])) # 140563140392256
print(id(v2[2])) # 140563140535744