2018-08-01-16-变量的作用域&变量的指向

变量的作用域

参考:https://blog.csdn.net/bylhjcsmmd/article/details/76372110

python的作用域并不是哪里都能访问的,分全局和局部的。

python变量的作用域大致分为已下四类:

  • L (local) 局部作用域
  • E (Enclosing) 闭包函数外的函数中
  • G (Global) 全局作用域
  • B (Built-in) 内建作用域

遵循LEGB原则

​ L->E->G->B

​ 按照这样的顺序进行查找

局部变量不能修改全局变量

>>> a = 1
>>> def func1():
	a +=1

	
>>> func1()
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    func1()
  File "<pyshell#7>", line 2, in func1
    a +=1
UnboundLocalError: local variable 'a' referenced before assignment

引入global,nonlocal

>>> a = 1
>>> def func2():
	global a		# 声明全局变量
	a +=1

	
>>> func2()
>>> print(a)
2
>>> def wrapper():
	x  = 1
	def inner():
		x +=1
	inner()
	print(x)

	
>>> wrapper()
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    wrapper()
  File "<pyshell#21>", line 5, in wrapper
    inner()
  File "<pyshell#21>", line 4, in inner
    x +=1
UnboundLocalError: local variable 'x' referenced before assignment
>>> def wrapper():
	x = 1
	def inner():
		nonlocal x	#  声明非局部变量
		x +=1
	inner()
	print(x)

	
>>> wrapper()
2

在python中,模块(module),类(class),函数(def,lambda)会产生新的作用域;

条件,控制语句,比如: (if...else) (for x in range(num)) (try...except...) 并不会改变变量的作用域。

重点理解

def add_end(L=[]):
	L.append('END')
	return L



函数的参数:
	⑴如果变量L的指向对象变了,L才变
	⑵如果变量L的指向对象没变,L不变
	  (就算指向对象自身的值发生了改变L也不变)


情况一:

>>> add_end([1,2,3])
[1, 2, 3, 'END']
>>> add_end(['a','b','c'])
['a', 'b', 'c', 'END']


情况二:

>>> def add_end(L=[]):
	L.append('END')
	return L

>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
>>> x=y=[]
>>> x.append('x')
>>> x
['x']
>>> y	# 也许你会想,y输出应该是[],but,you are wrong
['x']
# 为什么呢?
# 同样的代码,根据上下文的情景不同,会有不同的理解
#  我理解的是,这里调用的是x.append(),也就是x所指向的[]这个列表的方法
#  那么,实际发生修改的就是这个列表,
#  so, y也指向这个列表,那么y=['x']
对比
>>> x=y=[]
>>> x=1
>>> x
1
>>> y
[]
#  对比这里y 输出 []
#  这里,就是上下文的情景不同,x=1,
#  直接修改的是x这个变量,直接给x赋值=1
#  并没有影响到变量x原来指向的[]这个空列表
#  so, y=[]
#  y变量指向的[]列表没有发生任何变化
升级
函数版
>>> def main():
	lis = []
	func1(lis)	
	# 通过传参,把非局部变量传给嵌套函数,
	# so  内层函数就不用nonlocal声明,就可以修改
	print(lis)		#  查看修改后的lis

	
>>> def func1(lis):
	lis.append('a')

	
>>> main()
['a']
类版
>>> def main():
	lis = []
	a = A(lis)
	print(lis)	#  最后打印,查看一下修改后的lis

	
>>> class A(object):
	def __init__(self, lis):
		self.lis = lis
		self.lis.append('a')
        # 经典之处在这,self.lis.append()
        # 其实呢,self.lis = lis,
        # 与我们最开始的  x=y=[]  十分相似
        # 根据上下文的不同情景,同样的代码与不同的意义
        #  其实修改的值lis这个列表,或者说lis指向的内存地址

		
>>> main()
['a']
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值