-1

I have a variable ab = 2; Now I let's say we have this variable as a string 'a'+'b'. Based on this and this I know how to print the value of ab when I call it as a string. My question is how I can modify it when I have it as a string. For example:

class HELP:
    def __init__(self):
        self.ab = 2
        self.a2b2 = 2
        self.a3b3 = 2
        self.a4b4 = 2
        self.a5b5 = 2
        

        count = 1
        for k in [('a','b'),('a2','b2'),('a3','b3'),('a4','b4'),('a5','b5')]:
           print(eval('self.'+k[0]+k[1])) # this will return the value
           NewVar = 'self.'+'{}{}'.format(k[0],k[1])+'='+str(count*3)
           globals()[NewVar] = count*3
           count += 1
           
        for k in [('a','b'),('a2','b2'),('a3','b3'),('a4','b4'),('a5','b5')]:
           print(eval('self.'+k[0]+k[1]))
HELP()

will print:

2
2
2
2
2
2
2
2
2
2

but I expect to see:

2
2
2
2
2
3
6
9
12
15
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
sey eeet
  • 229
  • 2
  • 8
  • 4
    Are you sure you don’t want to use a dictionary? `d['a'] = 3` – mkrieger1 Oct 05 '20 at 19:23
  • 4
    This appears to be an [XY Problem](https://en.wikipedia.org/wiki/XY_problem). What are you doing in which an external entity references your program's internal variables by name? This is almost always faulty system design. – Prune Oct 05 '20 at 19:25
  • 1
    `globals()` / `locals()` gives you a dictionary of the variables in that scope. `getattr` gets the value of a key in a dict. If you absolutely must access a variable given only its name as a string, why do you not want to use `globals` or `locals`? – Pranav Hosangadi Oct 05 '20 at 19:26
  • @PranavHosangadi can you please write it as a solution so I understand better what do you mean? – sey eeet Oct 05 '20 at 19:49
  • @mkrieger1 hmmm dictionary sounds interesting actually, but I am not able to do it because I have `self.` in the name and it actually makes things messy kinda – sey eeet Oct 05 '20 at 19:50
  • @seyeeet This answer in the question you linked says all there is to say: https://stackoverflow.com/a/9437799/843953 – Pranav Hosangadi Oct 05 '20 at 19:50
  • @PranavHosangadi that answer is just for printing the variable, but how do you change the value of it via your suggestion – sey eeet Oct 05 '20 at 20:01
  • https://docs.python.org/3/library/functions.html#setattr or just set the value like you tried to do with `eval`. `globals()[varname] = value` – Pranav Hosangadi Oct 05 '20 at 20:03
  • @PranavHosangadi sorry I describe the question in a bad way, I think now it is what I exactly meant – sey eeet Oct 05 '20 at 20:07
  • @mkrieger1 sorry I describe the question in a bad way, I think now it is what I exactly meant – sey eeet Oct 05 '20 at 20:07
  • @PranavHosangadi `globals()[varname] = value` not working for my code, the value stays the same – sey eeet Oct 05 '20 at 20:18
  • IDK, works for me. https://i.stack.imgur.com/Og9fH.png – Pranav Hosangadi Oct 05 '20 at 20:20
  • @PranavHosangadi INTERESTING, Yeah it works when I do it outside the Class, but in the `def __init__` it wont work – sey eeet Oct 05 '20 at 20:32

3 Answers3

0

I think the easiest way is to use a dictionary like:

d={'a':2,
   'b':3
   }

print(d['a']) # outputs 2

for k in ['a']:
    d[k]=3
print(d['a']) # outputs 3

This method is very simple and effective. I also tried to do something like this once and it is so much easier just to use a dictionary.

SundyAgo
  • 63
  • 9
-1
>>> foo = 5
>>> foo
5
>>> exec("foo = 1337")
>>> foo
1337

You can do it with the exec function. It's not very safe but it works.

xanhacks
  • 122
  • 2
  • 5
  • why it is not safe? – sey eeet Oct 05 '20 at 19:53
  • Because if someone can control what's inside the exec function, it will be able to execute python code on your machine. – xanhacks Oct 05 '20 at 19:56
  • For example: exec("foo = 1337") Can be transform into (foo = import os; os.system('ls')#): exec("import os; os.system('ls')# = 1337") And get code execution on your machine – xanhacks Oct 05 '20 at 19:59
  • Thank you for your answer but I noticed that I describe the question slightly different from what I meant, I apologize for that. can you please see if your answer can be modified so it can address the new case – sey eeet Oct 05 '20 at 20:09
  • You can do the same with "ab". exec("ab = 3") – xanhacks Oct 05 '20 at 20:14
  • I see, it actually works, but there is a problem, I need to manually change the foo for each name, I had 100 variables. is there a way to prevent entering the names manually? – sey eeet Oct 05 '20 at 20:16
  • yes, I updated it. I just dont want to add anything manually, otherwise, I could do it manually from the begining – sey eeet Oct 05 '20 at 20:26
  • [**Do not ever use `eval` (or `exec`) on data that could possibly come from outside the program in any form. It is a critical security risk. You allow the author of the data to run arbitrary code on your computer.**](https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice) – Karl Knechtel Jul 05 '22 at 01:54
-1
>>> a2b2 = 2
>>> a3b3 = 2
>>> a4b4 = 2
>>> a5b5 = 2
>>> for i in range(2, 6):
...     exec(f"a{i}b{i} = {i*3}")
... 
>>> a2b2
6
>>> a3b3
9
>>> a4b4
12
>>> a5b5
15

You can do like this.

xanhacks
  • 122
  • 2
  • 5