直观的UnboundLocalError行为2的原因 [英] Reason for unintuitive UnboundLocalError behaviour 2

查看:62
本文介绍了直观的UnboundLocalError行为2的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跟进造成不直观的UnboundLocalError行为的原因(我假设您已经阅读). 考虑以下Python脚本:

Following up on Reason for unintuitive UnboundLocalError behaviour (I will assume you've read it). Consider the following Python script:

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的行有效!

The commented out lines (marked 1,2) are lines that would through an UnboundLocalError and the SO question I referenced explains why. However, the line marked 3 works!

默认情况下,列表是通过Python中的引用复制的,因此可以理解,当cc更改时c也会更改.但是,如果Python不允许直接从方法的作用域更改a和b,那么为什么为什么要首先允许c进行更改呢?

By default, lists are copied by reference in Python, therefore it's understandable that c changes when cc changes. But why should Python allow c to change in the first place, if it didn't allow changes to a and b directly from the method's scope?

我看不到默认列表是如何在Python中通过引用复制的事实会导致该设计决策不一致.

I don't see how the fact that by default lists are copied by reference in Python should make this design decision inconsistent.

我想念哪些人?

更新:

  • 为了完整起见,我还添加了与上述问题等效的字典,即我添加了源代码并用# Update
  • 标记了更新.
  • 为了进一步完整性,我还添加了等效项.套装的行为实际上令我惊讶.我希望它的作用类似于列表和字典...
  • For completeness I also added the dictionary equivalent to the question above, i.e. I added the source code and marked the update with # Update
  • For further completeness I also added the set equivalent. The set's behavior is actually surprisingly for me. I expected it to act similar to list and dictionary...

推荐答案

与字符串和整数不同,Python中的列表是 mutable 对象.这意味着它们被设计为可以更改的.线

Unlike strings and integers, lists in Python are mutable objects. This means they are designed to be changed. The line

c[0] += 'c'

等于说

c.__setitem__(0, c.__getitem__(0) + 'c')

,它不会对名称c绑定的名称进行任何更改.在此调用之前和之后,c是相同的列表–只是此列表的内容发生了变化.

which doesn't make any change to what the name c is bound to. Before and after this call, c is the same list – it's just the contents of this list that have changed.

你说过

c += ['c']
c = [42]

在函数f()中的

,将出现相同的UnboundLocalError,因为第二行将c用作本地名称,第一行将其翻译为

in the function f(), the same UnboundLocalError would have occured, because the second line makes c a local name, and the first line translates to

c = c + ['c']

要求名称c已经绑定到某个东西(在此本地范围内)尚未绑定.

requiring the name c to be already bound to something, which (in this local scope) it isn't yet.

这篇关于直观的UnboundLocalError行为2的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆