1

I'm a beginner programmer and I am trying to understand the difference between these three functions. Originally my problem is a bit different but I made it this easy for not to take your time a lot. I actually learned exec function today and no matter how much I try different variations with the function, I can't understand the difference between these v1 and v2. I want to use the v1 version but it doesn't change the variable p5. If anyone can clarify me I would be so glad.

NOTE: Original problem have p1,p2,p3,...,p9 and I get the index from the user input. So it is important to formatting string.

p5 = 5
index_of_p = 5


def change_p5_v1():
    exec(f"global p{index_of_p}")
    exec(f"p{index_of_p} = 3")
    print(p5)  # Output 5


def change_p5_v2():
    exec("global p5")
    exec("p5 = 3")
    print(p5)  # Output 5


def change_p5_v3():
    global p5
    p5 = 3
    print(p5)  # Output 3


change_p5_v1()
change_p5_v2()
change_p5_v3()
Begmattea
  • 11
  • 4
  • 1
    If you are a beginner, you should not be using `exec`. Period. Almost always, there is a faster, simpler, and safer way of achieving what you want. – Frank Yellin Mar 09 '23 at 17:51
  • I think I have exceeded my limits accidentally. Looking forward to learn the background of it. Thank you for your suggestion! – Begmattea Mar 09 '23 at 18:57

2 Answers2

2

You can specify the namespace you want to update in your exec call:

def change_p5_v1():
    exec(f"p{index_of_p} = 3", globals())
    print(p5)  # Output 3
jprebys
  • 2,469
  • 1
  • 11
  • 16
1

exec()s run one after the other are entirely separate; the first exec("global ...") doesn't affect the next exec().

Anyway, you should never use eval() or exec() unless you have some very specific need, and as a beginner, you, well, don't.

What you seem to be doing with p{index_of_p} is basically a dict, or "variable variables" - and since you're not assigning into p, you don't need global either.

p = {0: 0, 1: 10}
index = 0

def change_p():
    p[index] += 1

print(p)
change_p()
print(p)
change_p()
print(p)
index = 1
change_p()
print(p)
AKX
  • 152,115
  • 15
  • 115
  • 172
  • That's a wonderful suggestion. I'm a mathematics teacher because of that im used to say p1,p2.. etc. as an index. What you are saying to me is instead of doing that, create a dict, and instead of using p1, just use p[1]. Did I get it right? – Begmattea Mar 09 '23 at 18:55
  • Yes - or a list. May be worth it to reread python.org's tutorial regarding these data types. – AKX Mar 09 '23 at 20:53