在Python中,为什么list[]自动是全局的?

发布于 2024-11-15 07:20:20 字数 501 浏览 5 评论 0原文

这是一种奇怪的行为。

试试这个:

rep_i=0
print "rep_i is" , rep_i
def test():
  global rep_i #without Global this gives error but list , dict , and others don't
  if rep_i==0:
    print "Testing Integer %s" % rep_i
    rep_i=1
  return "Done"

rep_lst=[1,2,3]
 

def test2():
  if rep_lst[0]==1:
    print "Testing List %s" % rep_lst
  return "Done"


if __name__=="__main__":
  test()
  test2()

为什么列表不需要声明全局?它们自动是全局的吗?

我觉得这很奇怪,我大部分时间都使用列表,我什至根本不使用全局来将它们用作全局......

This is a weird behavior.

Try this :

rep_i=0
print "rep_i is" , rep_i
def test():
  global rep_i #without Global this gives error but list , dict , and others don't
  if rep_i==0:
    print "Testing Integer %s" % rep_i
    rep_i=1
  return "Done"

rep_lst=[1,2,3]
 

def test2():
  if rep_lst[0]==1:
    print "Testing List %s" % rep_lst
  return "Done"


if __name__=="__main__":
  test()
  test2()

Why list do not need to declare global? are they automatically global?

I find it really weird, I use list most of the time and I don't even use global at all to us them as global...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凝望流年 2024-11-22 07:20:20

它不会自动成为全球性的。

但是,rep_i=1rep_lst[0]=1 之间存在差异 - 前者重新绑定名称 rep_i,因此 global需要 来防止创建同名的本地槽。在后一种情况下,您只是修改一个现有的全局对象,该对象是通过常规名称查找找到的(更改列表条目就像调用列表上的成员函数,它不是名称重新绑定)。

要对其进行测试,请尝试在 test2 中分配 rep_lst=[](即将其设置为新列表)。除非您声明 rep_lst global,否则效果在 test2 外部将不可见,因为创建了同名的本地插槽并遮蔽了全局插槽投币口。

It isn't automatically global.

However, there's a difference between rep_i=1 and rep_lst[0]=1 - the former rebinds the name rep_i, so global is needed to prevent creation of a local slot of the same name. In the latter case, you're just modifying an existing, global object, which is found by regular name lookup (changing a list entry is like calling a member function on the list, it's not a name rebinding).

To test it out, try assigning rep_lst=[] in test2 (i.e. set it to a fresh list). Unless you declare rep_lst global, the effects won't be visible outside test2 because a local slot of the same name is created and shadows the global slot.

旧情别恋 2024-11-22 07:20:20

如果要分配全局名称,则只需使用global。如果没有global,赋值会创建一个新的局部变量。

global 如何应用于列表没有什么特别之处 - global 只是影响范围和名称解析。

You only need to use global if you are assigning to the global name. Without global, an assignment creates a new local.

There's nothing special about how global applies to a list—global simply influences scope and name resolution.

夏末 2024-11-22 07:20:20

python 中有一个名为 UnboundLocalError 的错误,它经常让新手感到困惑。令人困惑的是:未来赋值确实会改变变量的查找方式。

当解释器第一次看到变量名时,它会向前查找当前代码块的末尾,如果在同一代码块内的任何位置都没有对其进行赋值,则解释器会将其视为全局变量。但是,如果这样做,则它被视为本地,并且在赋值之前对它的任何引用都会生成 UnboundLocalError。这就是你得到的错误。这就是为什么您需要声明全局rep_i。如果您没有分配 rep_i,则不需要此行。

此外,这与变量类型无关。此外,向列表分配或附加一个项目(您可能打算这样做,但没有这样做)并不是列表本身的分配,它本质上是调用列表对象上的方法,这与分配不同:分配创建一个新对象(可能使用已存在的名称),而操作列表时只会更改现有列表。
您可以尝试:

In [1]: # It won't work with small integers, as they are cached singletons in CPython

In [2]: a = 123123

In [3]: id (a)
Out[3]: 9116848

In [4]: a = 123123

In [5]: id(a)
Out[5]: 9116740

In [6]: # See, it changed

In [7]: # Now with lists

In [8]: l = [1,2,3]

In [9]: id(l)
Out[9]: 19885792

In [10]: l[1] = 2

In [11]: id(l)
Out[11]: 19885792

In [12]: # See, it is the same

In [13]: # But if i reassign the list, even to the same value

In [14]: l = [2,2,3]

In [15]: id(l)
Out[15]: 19884272

There is an error in python called UnboundLocalError which often confuses newcomers. The confusing thing is: future assignment does change the way a variable is looked up.

When the interpreter sees a variable name for the first time, it looks ahead to the end of current code block, and if you don't have an assignment to it anywhere within the same block of code, the interpreter considers it global. If you do, however, then it is considered local, and any reference to it before assignment generates an UnboundLocalError. That's the error you got. That's why you need to declare global rep_i. If you did not assign rep_i, you wouldn't need this line.

Also, this has nothing to do with variable type. Also, assigning or appending an item to the list (which you probably meant to do, but did not) is not assignment of the list itself, it is essentially calling a method on a list object, which is different from assignment: assignment creates a new object (possibly under a name that already exists), while manipulating a list just changes an existing list.
You can try:

In [1]: # It won't work with small integers, as they are cached singletons in CPython

In [2]: a = 123123

In [3]: id (a)
Out[3]: 9116848

In [4]: a = 123123

In [5]: id(a)
Out[5]: 9116740

In [6]: # See, it changed

In [7]: # Now with lists

In [8]: l = [1,2,3]

In [9]: id(l)
Out[9]: 19885792

In [10]: l[1] = 2

In [11]: id(l)
Out[11]: 19885792

In [12]: # See, it is the same

In [13]: # But if i reassign the list, even to the same value

In [14]: l = [2,2,3]

In [15]: id(l)
Out[15]: 19884272
弥枳 2024-11-22 07:20:20

这是一个示例,演示了子例程中可以使用非 list/dict 变量,正如大家所说,问题在于重新绑定行为 code> 在原始代码示例中:

x = 1
def test():
    y = x + 1
    print y
test()

您将看到打印出 2,尽管 x 未声明为全局。

Here's an example that demonstrates that a non list/dict variable is available in a subroutine, and the problem is, as everyone says, the act of rebinding in your original code sample:

x = 1
def test():
    y = x + 1
    print y
test()

You'll see this prints out 2, despite x not being declared global.

谁把谁当真 2024-11-22 07:20:20

如果您为 test2 内部的 rep_lst 分配了一个新值(而不是像您那样仅分配给其元素之一),那么如果没有 global<,它将无法工作/代码> 标志。在Python中,如果你没有给函数内的变量赋值,它会在更全局的范围内查找该变量,直到找到为止。

例如,在此代码段中,我在全局和 example() 内部定义了列表。由于 example() 中的变量在范围上比全局变量更接近 example2(),因此将使用它。

x = ["out"]

def example():
    x = ["in"]
    def example2():
        print x # will print ["in"]

这与列表无关,而是 Python 中任何变量的行为。

If you had assigned a new value to rep_lst inside of test2 (not just to one of its elements, as you did) it would not work without the global flag. In Python, if you do not assign to a variable inside a function it will look for that variable in in more global scopes until it finds it.

For example, in this code segment I define the list both globally and inside of example(). Since the variable in example() is closer in scope to example2() than the global one is, it is what will be used.

x = ["out"]

def example():
    x = ["in"]
    def example2():
        print x # will print ["in"]

This has nothing to do with lists, but is the behaviour of any variable in Python.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文