-1

I have a python file values.py with the contents

a=10

I have another python file execute.py with the contents

from test.values import a

def changedata():
    with open("values.py",'r+') as f:
        text = f.read()
        new = a + 10
        text = text.replace(str(a), str(new))
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()

When I run the execute.py, ideally the contents of value.py should be a=40, but it is a=20

I fail to understand, why doesn't python change the contents of value.py on each iteration when run in a loop. Currently, the contents of value.py are only changed once even though it is run a in a loop. Can someone explain this behavior and also suggest a way to fix this.

martineau
  • 119,623
  • 25
  • 170
  • 301
Fuze Test
  • 31
  • 6
  • try removing `f.seek(0)` – EEAH Aug 21 '20 at 16:17
  • What is `from test.values import a`? when you do`str(a)` on the second loop? It sounds like `str(a)` might not be what you're expecting, so when it goes to do the replace, it doesn't find it? – jmunsch Aug 21 '20 at 16:17
  • 1
    You did not increment the value of `a` so it is always equal to `10`. Which means that your call to the `text.replace()` only works for the first call and not any subsequent ones. – domochevski Aug 21 '20 at 16:18
  • 2
    You never update the value of a, so it will always write the value of a + 10 – joshmeranda Aug 21 '20 at 16:19

4 Answers4

2

You only execute from test.values import a once, when the script first starts. That executes values.py, which assigns the a variable.

Rewriting the file doesn't cause the import to be executed again, so you never reassign a with the new value from the file. And even if you re-executed the import statement, it wouldn't be updated, as Python remembers which modules have been imported and doesn't re-import them (see python import multiple times).

To keep adding to the value in the file, you'll need to run your whole script repeatedly, not just call changedata() in a loop. Or you could have changedata() update the a variable instead of using new.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Although you change the contents of values.py and you expect the value of a to update accordingly it does not happen. That's because python is not constantly watching loaded modules to reload them in case they were changed. Check this answer out, it's pretty similar to yours: How do I reload a module after changing it?

Mohammad Jafar Mashhadi
  • 4,102
  • 3
  • 29
  • 49
1

To elaborate on Barmar's comment, your problem is that you are not updating the value of a each time through the loop. a is always 10 (and would still be 10 even if you reimport it after overwriting the file because, as Barmar noted, Python is smart enough to not reimport what has already been imported). To get around this, you need to change the value that you are seeking to overwrite with each iteration. One simple way to do this would be to pass a variable to the function like so:

from values import a

def changedata(data):
    with open("values.py",'r+') as f:
        text = f.read()
        new = data + 10
        text = text.replace(str(data), str(new))
        f.seek(0)
        f.write(text)
        f.truncate()
        return new

for i in range(0,4):
    a = changedata(a)

In this code, a is passed as a variable to the function changedata() which then seeks to overwrite the previous value of a in values.py with the new value, a + 10. But the function then returns this new value and the line a = changedata(a) overwrites the value of a to the value a + 10 so in the next iteration, changedata() is correctly seeking to overwrite this new value. The original value of a would no longer be found in the file values.py since it has been overwritten by a + 10 in the first iteration.

thehumaneraser
  • 632
  • 4
  • 21
0

Here you are:

I use an extra variable tmp. I your code the replace method search always for 10 to replace it. But only the first time find the number 10. All the others times 10 does not exists into values.txt

from test.values import a

tmp = a

def changedata():
    global tmp
    with open("values.py",'r+') as f:
        text = f.read()
        print(text) 

        new = tmp + 10
        
        text = text.replace(str(tmp), str(new))
        tmp = new
        
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()

or without the usage of a global variable and without import the a:


def changedata():
    with open("values.py",'r+') as f:
        text = f.read()
        print(text) 

        array = text.split("=")

        tmp = int(array[1])
        new = tmp + 10
        
        text = text.replace(str(tmp), str(new))
        
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()
Manolis P.
  • 195
  • 2
  • 14