Is there a way to turn a string into a usable object?

Viewed 43

So I am creating a program that has different possible string outputs. For example, the outputs could either be "a", "b", or "c". However I want to be able to use these outputs as an object. I already have objects initialized as a b and c. For example:

class Letter:
  pass

a = Letter()
b = Letter()
c = Letter()

output = random.choice(["a", "b", "c"])

#for example it would output "a"
#then I would "call" (lack of a better term) the a object to do something with it
#basically the output decides which object I would use

a.color = "green"
4 Answers

You can make dict to check, which object needs to be used.

ouput = random.choice("a", "b", "c")
output_var_dict = {"a": a, "b": b, "c": c}

output_var_dict[ouput].color = green

OR

not recommended


globals().update({output: Letter()})
a.color="green"

Use the objects directly:

output = random.choice([a, b, c])

output.color = 'green'

Note that this alerts the original object.

For working on copies:

from copy import copy

l = [a, b, c]
output = random.choice([copy(x) for x in l])

output.color = 'green'

Just use random.choice([a, b, c]) instead of random.choice(["a", "b", "c"])

Which will give you the random object.

Using eval you can turn a string into a python object, see doc.

letters = ["a", "b", "c"]
output = random.choice(letters)

char = eval(letters[0])
print(char)
# a

To prevent "side effects" of string evaluation you can restrict the scope:

letters = ["a", "b", "c"]
output = random.choice(letters)

char = eval(letters[0], {}, dict(zip(letters, letters)))
print(char)
# a  # still works because it is in the dictionary
new_output = 'x'
char = eval(new_output, {}, dict(zip(letters, letters)))
# NameError: name 'x' is not defined

x does not belongs to the local namespace described by the dictionary dict(zip(letters, letters))

In your case you should pass as local namespace dict(Letter=Letter)

Related