作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
跟进 Reason for unintuitive UnboundLocalError behaviour (我假设你已经读过了)。考虑以下 Python 脚本:
def f():
# a+=1 # 1
aa=a
aa+=1
# b+='b' # 2
bb=b
bb+='b'
c[0]+='c' # 3
c.append('c')
cc=c
cc.append('c')
d['d']=5 # Update 1
d['dd']=6 # Update 1
dd=d # Update 1
dd['ddd']=7 # Update 1
e.add('e') # Update 2
ee=e # Update 2
ee.add('e') # Update 2
a=1
b='b'
c=['c']
d={'d':4} # Update 1
e=set(['e']) # Update 2
f()
print a
print b
print c
print d # Update 1
print e # Update 2
脚本的结果是:
1
b
['cc', 'c', 'c']
{'dd': 6, 'd': 5, 'ddd': 7}
set(['e'])
注释掉的行(标记为 1,2)是将通过 UnboundLocalError 的行,我引用的 SO 问题解释了原因。但是,标记为 3 的行有效!
默认情况下,列表在 Python 中通过引用进行复制,因此当 cc 更改时 c 更改是可以理解的。但是,如果 Python 不允许直接从方法的范围内更改 a 和 b,为什么 Python 首先要允许更改 c?
我不明白在 Python 中默认列表是通过引用复制的事实应该如何使这个设计决策不一致。
我想念什么伙计们?
更新:
# Update
标记了更新最佳答案
与字符串和整数不同,Python 中的列表是可变 对象。这意味着它们是为改变而设计的。线路
c[0] += 'c'
等同于说
c.__setitem__(0, c.__getitem__(0) + 'c')
这不会对 c
绑定(bind)的名称做任何更改。在此调用前后,c
是相同的列表 – 只是此列表的内容发生了变化。
你说过吗
c += ['c']
c = [42]
在函数 f()
中,同样的 UnboundLocalError
会发生,因为第二行使 c
成为局部名称,并且第一行翻译成
c = c + ['c']
要求名称 c
已经绑定(bind)到某个东西,(在这个本地范围内)它还没有。
关于python - UnboundLocalError 行为不直观的原因 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4534134/
我是一名优秀的程序员,十分优秀!