178

I have a variable with a string assigned to it and I want to define a new variable based on that string.

foo = "bar"
foo = "something else"   
# What I actually want is:    
bar = "something else"
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
9-bits
  • 10,395
  • 21
  • 61
  • 83
  • 26
    You probably DON'T want that. Why are you trying to do it? – JBernardo Jul 19 '12 at 04:03
  • 5
    No you don't. The reason you have to use `exec` is because `locals()` doesn't support modifications. `locals()` doesn't support modifications because it would make the implementation more complex and slower and is **never** a good idea – John La Rooy Jul 19 '12 at 04:04
  • 2
    Similar Post: http://stackoverflow.com/questions/1373164/how-do-i-do-variable-variables-in-python – Kartik Jul 19 '12 at 04:08
  • 1
    I landed on this post trying to find out how to assign instance variables for a class using a dictionary. If anybody else has the same problem, you can find a clean solution without exec here: https://stackoverflow.com/questions/8187082/how-can-you-set-class-attributes-from-variable-arguments-kwargs-in-python – Alice Schwarze Feb 10 '19 at 01:27

3 Answers3

284

You can use exec for that:

>>> foo = "bar"
>>> exec(foo + " = 'something else'")
>>> print bar
something else
>>> 
Jack Leow
  • 21,945
  • 4
  • 50
  • 55
  • 133
    +1 because he answered the question (as bad an idea as it may be). – mgalgs Jun 25 '13 at 03:39
  • 4
    @mgalgs why it's a bad idea? Any bad effect this solution have? Thanks in advance. – Clock ZHONG Nov 16 '18 at 07:41
  • 7
    Note use of `exec` / `eval` is [considered poor practice](https://stackoverflow.com/a/1832957/9209546). I have not met a single use case where it has been helpful, and there are *usually* better alternatives such as `dict`. – jpp Jan 12 '19 at 00:04
  • why doesn't this work when used in pytest unittests? – niCk cAMel Sep 02 '19 at 09:24
  • +100 what @jpp said. While this answer is useful and correct, if you're writing something other than a one-off script, you can most likely use a `dict`. – Olshansky Apr 25 '20 at 01:11
  • @jpp It does, albeit much more niche than this. https://lucumr.pocoo.org/2011/2/1/exec-in-python/ – Xwtek Jun 26 '20 at 04:39
  • I found what seems like an optimal use case of exec() in turtle.py: setting all public class methods to work as global functions. If you have a better way of doing this that does not use exec(), please answer my question here: https://stackoverflow.com/questions/66393376/is-it-possible-to-automatically-make-all-of-a-modules-public-class-methods-glob – Ryan Laursen Feb 27 '21 at 00:50
  • doesn't work. wtf exec???? – ArraffaFile Nov 06 '22 at 16:11
  • This is the best "direct" answer, but I think it should contain a claim indicating you might not want to follow it... (and linking to other answers) – Kalo Jun 26 '23 at 10:19
173

You will be much happier using a dictionary instead:

my_data = {}
foo = "hello"
my_data[foo] = "goodbye"
assert my_data["hello"] == "goodbye"
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 59
    It does not seem to address the question. – dnsmkl Nov 05 '15 at 19:52
  • 8
    Yes. This may be helpful, but it wasn't what the OP was asking. – sudo Jun 06 '16 at 18:52
  • 58
    I'm glad to see the answer is still here. I think we can trust Stack Overflow readers to judge for themselves whether an answer suits their needs. This answer does not provide "variable variables," it is true. But I guarantee you that 99% of the people looking for them will be happier to have found dictionaries. – Ned Batchelder Jun 06 '16 at 23:55
  • 7
    It does not DIRECTLY answer the question, however, people might be asking that question while ignoring they can use a dictionary for the same purpose – Berto 'd Sera Apr 01 '18 at 17:18
  • 9
    "I'm cold, how can I set my house on fire?" – Ned Batchelder Mar 10 '20 at 16:48
  • I would argue it does answer the question. I think OP is asking for: foo = "bar" foo = "something else print(bar) ------------- output: "Something else" – Matt Nov 06 '21 at 01:50
121

You can use setattr

name  = 'varname'
value = 'something'

setattr(self, name, value) #equivalent to: self.varname= 'something'

print (self.varname)
#will print 'something'

But, since you should inform an object to receive the new variable, this only works inside classes or modules.

Demis
  • 5,278
  • 4
  • 23
  • 34
Gustavo Vargas
  • 2,497
  • 2
  • 24
  • 32
  • 16
    Correct, it only works inside classes. – sudo Jun 06 '16 at 18:53
  • 1
    Can this be used inside Modules, so set a module-level attribute? Eg. `MyModule.var` – Demis Apr 26 '20 at 03:15
  • 3
    To answer my own question, yes, it can be used from within a module, on itself: https://stackoverflow.com/questions/2933470/how-do-i-call-setattr-on-the-current-module – Demis Apr 26 '20 at 04:47