2

有没有办法在子函数和父函数之间交换不是列表的变量?

#parent

list=[0]*1
singlevalue = 0

#child - 0
def test():
    list[0]= list[0]+1
    return list

#parent
test() #>>1 
test() #>>2


#child - 1
def test():
    singlevalue = singlevalue +1
    return singlevalue

#parent
test() >>
#    singlevalue = singlevalue +1
#UnboundLocalError: local variable 'singlevalue' referenced before assignment

该示例向您展示了 list 它输出 1 并保留它以供下次执行。为什么单值有不同的方式?

4

3 回答 3

2

到目前为止,这两个答案都提出了一个解决方案,这不是帖子的重点。不同之处在于,关于列表,您使用的是引用,而不是像使用singlevalue. 只要您尝试这样做:l = l + [1]例如,您将尝试修改边界l并得到相同的错误。那是因为 python 的作用域是如何工作的!

简而言之

singlevalue [local variable] = singlevalue [actually a global variable but access to locally stored variable] + 1 [constant]

单值存储在本地。现在它想要访问本地存储的变量,该变量还没有值,因为它没有被赋值。如果要全局存储它,则需要使用global关键字。

list[0] [slot in a referenced list] = list[0] [still same slot, which has a value already]+1

因此,没有问题。:)

更详细

我们可以在这里看看python的字节码,看看加载的不同:

>>> def m():
...  y = 1
...  def test():
...   y = y + 1
...   return y
...  test()
>>> m()
UnboundLocalError: local variable 'y' referenced before assignment
>>> dis.dis(m)
  [... cur here ... Inside of test()]
              # <-- here the value of the constant is loaded from the local namespace
  3           6 LOAD_CONST               2 (<code object test at 02A067B8, file "<pyshell#33>", line 3>)                   
              9 MAKE_FUNCTION            0
             12 STORE_FAST               1 (test)
  [... cut here ...]

>>> def l():
...  li = [1]
...  def test():
...   li[0] = li[0] + 1
...   return li
...  test()
>>> l()
[... cut here ... Inside of test()]
              # <-- here a reference is loaded!
  3           9 LOAD_CLOSURE             0 (li)
             12 BUILD_TUPLE              1
             15 LOAD_CONST               2 (<code object test at 02A06698, file "<pyshell#28>", line 3>)
             18 MAKE_CLOSURE             0
             21 STORE_FAST               0 (test)
[... cut here ...]

由于这篇文章会变得太长,我建议执行上面的命令并在这里查看:http: //docs.python.org/2/library/dis.html看看有什么不同!

然而,存储方式的主要区别发生在第一个块中:

  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (y) # <- push loaded constant to stack

  2           0 LOAD_CONST               1 (1)
              3 BUILD_LIST               1
              6 STORE_DEREF              0 (li) # <- stores the value in the list

看看这里

我希望这有助于消除差异。干杯!

于 2013-06-17T07:58:05.883 回答
1

查看有关如何传递参数的定义函数会有所帮助吗?

传递参数可能比操纵一个你希望它是全局可访问和可变的“变量”更可靠。

实际上,“变量”是(特定)命名空间中引用的名称,如果您要检查

print id(ll)    # as suggested by others: please don't name your list list ;)
print id(singlevalue)

在您的功能中,您会看到它们没有改变。因此,您可以在任何函数中引用名称单值并毫无问题地打印它。

当试图改变他们的价值观时,情况发生了变化:

列表是可变对象,您可以在不更改引用的情况下(在任何函数中)处理它们。将它们作为参数传递是否是更好/更性感/更pythonic的想法是另一点。

然而,字符串是不可变的。在您的函数中,您可以将singlevalue的值分配给另一个名称,并且这两个名称将具有相同的引用。但是当您更改新名称的值时,它将有一个新的引用!

因此,我建议尽可能懒惰,但最好传递数据,而不是在“周围”命名空间中四处寻找,并希望你能做到最好;)

于 2013-06-17T07:51:28.063 回答
0

不要使用全局变量。每次只需重新分配变量的值。

some_variable = 0
def test():
    return some_variable + 1


some_variable = test()  # 1
some_variable = test()  # 2

交互式解释器上的测试会话:

>>> a = 0
>>> def test():
...     return a + 1
... 
>>> a = test()
>>> a
1
>>> a = test()
>>> a
2
于 2013-06-17T08:01:42.103 回答