加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python =与全局变量中的函数内的.extend()

发布时间:2020-12-16 21:38:24 所属栏目:Python 来源:网络整理
导读:我已经阅读了其他一些SO( PythonScope和 globals don’t need global)但似乎并没有像我想的那样明确解释,我在精神上筛选 PyDocs是否告诉我问题的答案: myList = [1]def foo(): myList = myList + [2,3]def bar(): myList.extend([2,3])def baz(): myList +=
我已经阅读了其他一些SO( PythonScope和 globals don’t need global)但似乎并没有像我想的那样明确解释,我在精神上筛选 PyDocs是否告诉我问题的答案:
myList = [1]

def foo():
    myList = myList + [2,3]
def bar():
    myList.extend([2,3])
def baz():
    myList += [2,3]

现在,可以理解,

>>> foo()
UnboundLocalError

bar()  # works
myList # shows [1,2,3]

但是之后

>>> baz()
UnboundLocalError

然而,我认为像=隐式调用方法运算符,在这种情况下是extend(),但错误意味着由于某种原因它实际上不会将=视为extends().这与Python解析应该如何工作一致吗?

我本以为调用与方法运算符等效的函数,它们在所有情况下都是等价的.相反,似乎它将=视为实际的赋值运算符.除此之外,这并不完全正确,因为如果我做了某些事情(诚然做作):

myList = range(50000000) # wait a second or two on my laptop before returning
myList += [0]            # returns instantly
myList = myList + [1]    # wait a second or two before returning

所有这些都是预期的,如果=实际上只是调用extend().

我是否缺少一些更精细的区别(或非常明显的点……),这表明baz()中的myList需要被视为局部变量,因此=不能隐式转换为扩展()使它识别全局变量?

解决方法

=不会隐式调用extend().首先是 augmented assignment operator.

如果你看一下有关任务的部分,它会说:

Assignment of an object to a single target is recursively defined as follows.

If the target is an identifier (name):

If the name does not occur in a global statement in the current code block: the name is bound to the object in the current local namespace.
Otherwise: the name is bound to the object in the current global namespace.

由于增强的任务是:

Augmented assignment is the combination,in a single statement,of a binary operation and an assignment statement:

它遵循相同的规则.
如你看到的:

>>> def baz():
        myList += [2,3]


>>> dis.dis(baz)
  2           0 LOAD_FAST                0 (myList)
              3 LOAD_CONST               1 (2)
              6 LOAD_CONST               2 (3)
              9 BUILD_LIST               2
             12 INPLACE_ADD         
             13 STORE_FAST               0 (myList)
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE

An augmented assignment evaluates the target (which,unlike normal assignment statements,cannot be an unpacking) and the expression list,performs the binary operation specific to the type of assignment on the two operands,and assigns the result to the original target. The target is only evaluated once..

第一个调用trys来评估myList,这导致LOAD_FAST,因为没有全局语句,它被假定为局部变量:

LOAD_FAST(var_num)

Pushes a reference to the local co_varnames[var_num] onto the stack.

它无法找到,因此引发了错误.如果找到了,那么我们到了oppcode INPLACE_ADD,它调用方法myList .__ iadd__来完成扩展的工作,一旦这个操作完成,结果将被分配回变量,但我们永远不会这么做.

你不应该真的操纵全局变量,从函数返回新结果或将其作为参数传递.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读