我编写了一个程序,它使用线程模块创建一个向先前定义的变量添加1的线程,但是,一旦程序终止,变量的值仍然相同。我试过这个:
from threading import Thread
def plus_one(var):
return var + 1
var = 0
print var
my_adder = Thread(target = plus_one, args = (var, ))
var = my_adder.start()
my_adder.join()
print var
但它不起作用......我该怎么办?我已经搜索了一些信息,但这一切都让人很困惑......!
答案 0 :(得分:1)
Python仅通过引用传递对象,标量值通过值传递。那么,如果你定义一个类
class IntWrapper(object):
val = 1
def incr(obj)
obj.val += 1
那将有效
答案 1 :(得分:1)
在python中,你没有'变量',你不能'通过引用传递'或'按值传递'。你有'名字',它被绑定到内存中的值。这些值可以更改,或者名称可以更改。例如:
>>> x = 21
>>> y = x
>>> y
21
>>> x = 100
>>> y
21
创建函数时,任何值更改的名称都会被视为新名称,并且不会指向外部名称:
>>> x = 21
>>> def do(a):
x = a + 100 # x here is a new local name, since you've assigned to it.
>>> do(x)
>>> x
21
但是,如果您所做的只是读取名称,那么python将允许您从父“范围”中读取变量:
>>> x = 21
>>> def p():
print (x)
>>> p()
21
这是您的代码的第一个问题。这样做的方法是使用全局定义的名称,并告诉函数使用该全局名称:
>>> x = 21
>>> def do():
global x
x = 41
>>> do()
>>> x
41
(在python 3中,您可以使用nonlocal
而不是global
来访问父作用域中的非全局名称。
当您返回一个值时,您需要在与其定义的范围相同的范围内为该值指定名称。
如果将名称绑定到数字,元组或字符串之类的值,则值为immutable
。你无法改变它。因此,每当您说x = 1
然后x = 21
时,您不会更改x的值,而是重新绑定x以指向新值。这就是y = x
示例y没有改变的原因。它仍然受旧价值的束缚。值没有改变,但x
现在指向一个新值。
然而,并非python中的所有内容都是不可变的。列表,词组,对象等不是不可变的。所以:
>>> x = [100]
>>> def do(l):
l[0] = 50
>>> do(x)
>>> x
[50]
此外:
>>> x = [21]
>>> y = x
>>> x[0] = 50
>>> y
[50]
如果你真的需要,这可以用来'通过引用传递值'。但是,如果你滥用它,通常是一个好的迹象,不知何故代码的结构是错误的。
您正在做的是返回一个新值,但不会将其分配到任何地方。线程.start()
方法不起作用。原因是,如果它确实如此,那么你将阻塞当前线程(实际上将名称绑定到新值),等待返回新值以将其设置为的那个,这将错过线程点
您可以使用上述方法解决此问题。
你真正需要注意的一件事是,如果多个线程试图同时访问相同的值,那么从多个线程访问的变量可能相当可怕,事情表现不正常。
这是一篇关于'锁'的非常好的文章,以及如何安全地使用线程。
http://effbot.org/zone/thread-synchronization.htm
享受!
答案 2 :(得分:0)
为此你应该将你的变量初始化为0
在声明时也会更改您的变量名称
因为var是一个自己的关键字所以最好使用另一个变量