0

let's say I have 4 classes. I would like to create a single instance of a specific class, defined by input.

for example:

class A:
    def __init__(self, arg):
        self.attr = arg

...

class E:
    def __init__(self, arg):
        self.attr = arg

chosen_class = input('choose your class: ')
instance1 = chosen_class(self, arg)

the problem is that the class name recognized as a string and the error that shown is 'str' object has no attribute.

my question is - How can I unwrap this string in order to use it as my class name?

from this: instance = 'A'(self)

to this: instance = A(self)

Thanks in advance!

Samwise
  • 68,105
  • 3
  • 30
  • 44
Ben
  • 1
  • 1
  • 3
    How about you create a dictionary and accept the user input as the key and the corresponding class as the value? – rahlf23 Apr 22 '20 at 23:50
  • You have to create that mapping somehow, Generally, a `dict` would be a choice to map strings to arbitrary objects, but you could use an `if-elif-else` statement as well, for example. – juanpa.arrivillaga Apr 22 '20 at 23:53
  • 2
    This would be quite brittle. What if you change the class name? Should users need to adapt to a implementation detail like that? – Carcigenicate Apr 22 '20 at 23:53

2 Answers2

0

One way to do it is as follows:

class A:
    def __init__(self, arg):
        self.attr = arg

class B:
    def __init__(self, arg):
        self.attr = arg

mapping = {'A': A, 'B': B}
chosen_class = mapping[input('choose your class: ')]
A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
0

The answer to your question is eval, but you should not actually do this:

>>> class A:
...     def __init__(self, arg):
...         self.attr = arg
...
>>> class E:
...     def __init__(self, arg):
...         self.attr = arg
...
>>> instance1 = eval(input('choose your class: '))("foo")
choose your class: A
>>> instance1
<__main__.A object at 0x035F81D8>

because it's very unsafe on many levels. Use something like a lookup dict. For example:

>>> class_lookup = {
...     'A': A,
...     'E': E,
... }
>>> instance1 = class_lookup[input('choose your class: ')]("foo")
choose your class: E
>>> instance1
<__main__.E object at 0x035F8118>
Samwise
  • 68,105
  • 3
  • 30
  • 44
  • Why put the unsafe solution before the safe and recommended one? – AMC Apr 23 '20 at 00:11
  • Because it's literally the exact thing they asked for. I wanted to go ahead and answer their question before giving them my unsolicited advice. :) – Samwise Apr 23 '20 at 00:18