有没有办法在子函数和父函数之间交换一个不是列表的变量?
#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并保留它以供下次执行。 为什么单值有不同的方式?
答案 0 :(得分: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
看看here!
我希望这有助于消除差异。干杯!
答案 1 :(得分:1)
查看defining functions如何传递参数会有帮助吗?
传递参数可能比操纵一个“变量”更可靠,你希望它可以全局访问并且可变。
实际上,“变量”是(特定)命名空间中引用的名称,如果您使用
进行检查print id(ll) # as suggested by others: please don't name your list list ;)
print id(singlevalue)
在你的功能中,你会发现它们没有改变。因此,您可以在任何函数中引用名称 singlevalue 并打印它没有任何问题。
当尝试更改其值时,情况会发生变化:
列表是可变对象,你可以乱用它们(在任何函数中)而不改变它们的引用。将它们作为参数传递给它是否是更好/更性感/更多的pythonic想法是另一个观点。
然而,字符串是不可变的。在您的函数中,您可以将 singlevalue 的值分配给另一个名称,并且两个名称将具有相同的引用。但是当你改变新名字的价值时,它会有一个新的参考!因此,我建议尽可能地保持懒惰,但更好地传递数据而不是在“周围”命名空间中徘徊并希望你最好;)
答案 2 :(得分: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