Reputation: 37
import threading
from time import sleep
v1 = 100
dictionary = {'key':v1}
def fn1():
global v1
for i in range(30):
sleep(0.2)
v1 = i
def fn2():
global dictionary # this line is totatlly unnecessary, I know
for i in range(30):
sleep(0.2)
print(dictionary['key'])
th1 = threading.Thread(target=fn1)
th1.start()
th2 = threading.Thread(target=fn2)
th2.start()
This code outputs only 100's, I would want it to output 1, 2, 3 ... Changing value in dictionary is not really a solution - it needs to work in a quite more complex situation, but will rewrite if necessary
Thanks!
Upvotes: 1
Views: 119
Reputation: 39404
One option you have is to have some indirection:
v1 = [100]
dictionary = {'key':v1}
def fn1():
global v1
for i in range(30):
sleep(0.2)
v1[0] = i
def fn2():
global dictionary # this line is totatlly unnecessary, I know
for i in range(30):
sleep(0.2)
print(dictionary['key'][0])
This uses a list to hold the integer as the first item.
Now the dict holds a reference to a list which is the same list all the time.
Upvotes: 1
Reputation: 511
To provide a little more insight as to what is happening:
When you create the dictionary v1 points to 100 and the reference to the value 100 is copied to the dictionary dictionary = {'key':v1}
>>> d={'key':v1}
>>> id(v1)
140715103675136
>>> id(d['key'])
140715103675136
As you can see both v1 and the dict point at the same location in the memory.
In the loop you then change the reference where v1 points to and once it is finished it will point to where Python stores the value 29. However the loop never updates the reference where your dictionary points to.
If you want to change the value of the dictionary you could use a mutable type, such as a list and then pop the elements.
v1 = [100]
dictionary = {'key': v1}
def fn1():
global v1
for i in range(30):
sleep(0.2)
v1.append(i)
#or: v1[0] = i
def fn2():
global dictionary # this line is totatlly unnecessary, I know
for i in range(30):
sleep(0.2)
print(dictionary['key'].pop[0])
#or:print(dictionary['key'][0])
Upvotes: 2