当在函数中使用没有声明过的变量时,Python 的搜索顺序是:
local)enclosing)global)build-in)如下例子,
c 在局部作用域 ( local ) 被发现;b 在 parent 函数和 son 函数间( enclosing )被发现;a 在全局作用域( global )被发现 ;min 函数属于 Python 中 内置函数 ,所以在搜寻完 LEG 三个区域后,最终在 build-in 域被找到;a = 10
def parent():
b = 20
def son():
c = 30 # c: local
print(b + c) # b: enclosing
print(a + b + c ) # a: global
print(min(a,b,c)) # min : built-in
son()
In [72]: parent()
50
60
10
如下变量 d,在 LEGB 四个域都被搜寻一遍后,还是未找到,就会抛出 d 没有被发现的异常。
a = 10
def parent():
b = 20
def son():
c = 30 # c: local
print(b + c) # b: enclosing
print(a + b + c ) # a: global
print(min(a,b,c)) # min : built-in
print(d) # 在 LEGB 四个域都未找到后,报错!
son()
parent()
# NameError: name 'd' is not defined
当使用下面的操作的时候,会产生浅拷贝的效果:
[:]list 、dir、 set)copy 模块中的 copy() 函数,只会复制父对象,而不会复制对象内部的子对象;深拷贝:
copy.deepcopy 是深拷贝,会复制对象及其子对象;In [11]: import copy
In [12]: a = [1,2,3, ['a', 'b']]
In [13]: b = a
In [14]: c = a[:]
In [15]: d = copy.copy(a)
In [16]: e = copy.deepcopy(a)
In [17]: id(a)
Out[17]: 62660040L
In [18]: id(b)
Out[18]: 62660040L
In [19]: id(c)
Out[19]: 62660424L
In [20]: id(d)
Out[20]: 62519944L
In [21]: id(e)
Out[21]: 62520776L
从上可以看出:
= 赋值,它的 id 是和 a 本身是一样的;[:] 切片赋值和 copy.copy() 赋值的 id 是一样的,它们都是浅拷贝;copy.deepcopy() 赋值的 id 是和其它都不一样,它是深拷贝;为啥叫做深拷贝,看下面。
In [12]: a[0] = 'aaa'
In [13]: a[3].append('c')
In [14]: a
Out[14]: ['aaa', 2, 3, ['a', 'b', 'c']]
In [15]: b
Out[15]: ['aaa', 2, 3, ['a', 'b', 'c']]
In [16]: c
Out[16]: [1, 2, 3, ['a', 'b', 'c']]
In [17]: d
Out[17]: [1, 2, 3, ['a', 'b', 'c']]
In [18]: e
Out[18]: [1, 2, 3, ['a', 'b']]
增加补充查看 d 和 e 中内部子列表的 id 值。