-2

I'm new in python, and need some help here:

The user enters an identifer (project name, client name) through the GUI or controle screen. This text entered by the user should be the identifier that automatically instantiates a Class:

identifier = Class()

Question: how can I do that in python? (so far as I have seen in videos, every instantiation was done directly from a variable typed inside the code...)

  • Just get the name from `input()`, then use `exec()`, as per [Dynamically Load Classes in Python](https://stackoverflow.com/questions/21058188/dynamically-load-classes-in-python) – smci Mar 17 '22 at 20:38
  • Also, if you want a full design pattern: [Can you use a string to instantiate a class?](https://stackoverflow.com/questions/553784/can-you-use-a-string-to-instantiate-a-class/) – smci Mar 17 '22 at 20:42
  • Wow! I didn't expect for so many hints in such a short time! I am already opening the links to see if the sugestion applies - thank you very much! – Paulo Blaud Mar 17 '22 at 20:48
  • Are you wanting to dynamically decide the variable name or the class being instantiated? – hostingutilities.com Mar 17 '22 at 21:08
  • After reading the links, I realized they handle with a different version of my problem (much more complex) and I couldn't see how to use exec() or the other sugestions thereof to solve my problem. – Paulo Blaud Mar 17 '22 at 21:18
  • All I need is to get the string typed in by the user and transform it in a variable in order to instantiate a class. (if the user types in PROJECT1, then it will be lowered() to project1 and then instantiation proceeds: project1=Klass() ..... any other hint? – Paulo Blaud Mar 17 '22 at 21:20
  • hostingutilities, good afternoon! The class is fixed. The instances should be a string typed in by the user, like "client1, project1, etc" – Paulo Blaud Mar 17 '22 at 21:24

3 Answers3

0

You can use a bunch of if statements to decide which class to instantiate

user_input = input()
if user_input == 'myClass': 
    identifier = myClass()
elif user_input == 'anotherClass':
    identifier = anotherClass()
...

You don't want to just blindly accept any input from the user because of security issues. There is eval and exec, but you would be basically giving the user free reign to also run whatever code they want by using those.

If you have more than a few classes, then instead of if statements you can use a dictionary like so.

inputs_to_classes = { 'myClass': myClass, 'anotherClass': anotherClass }
user_input = input('Enter a class to instantiate: ').lower()
identifier = inputs_to_classes[user_input]()

Or in Python 3.10+ you could use a match expression, but I don't currently have access to Python 3.10.

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
0

the correct answer in this case is: don't do this. (and yes, it's possible to do this, but again, don't do this)

Essentially, your user should not even need to be made aware of what variables are, and should absolutely not be controlling what variable names are created in your code dynamically for your objects of these classes.

So, one actual solution that bypasses this issue is to just use a dictionary. take a string from user, that's a key in a dictionary. initialize your class against the key in the dictionary, and just use the key to access the class.

Another, perhaps better solution, is to just have your class take an extra name attribute. when you need to display the name the user entered for the class, you access it on the attribute. Then you do not even need to use a dictionary, you just create the class with your own variable name internally, but always display the user entered name from it's attribute. This separates concerns between what the user knows and what the programmer should deal with.

# Recommended solution
class Project:
    def __init__(self, name, other_params):
        self.name = name
        self.other_params = other_params
    def some_method(self, extra_args):
        pass

class Client:
    def __init__(self, name, other_params):
        self.name = name
        self.other_params = other_params
    def some_method(self, extra_args):
        pass


# these can come from your gui instead of input, doesn't matter
project_user_input = input("enter project name: ")
# these can come from your gui instead of input, doesn't matter
client_user_input = input("enter client name: ")


# make the actual objects, your variable names are internal to you,
# and the names themselves should not be tied to business logic.
# use the .name method to access the user-facing names.
project_obj = Project(name=project_user_input, other_params=42)
client_obj = Client(name=client_user_input, other_params=100)

# you can always access user facing names as necessary.
print(f"the project has the name: {project_obj.name}")
print(f"the client has the name: {client_obj.name}")
Paritosh Singh
  • 6,034
  • 2
  • 14
  • 33
-2
  1. Decide on gui framework
  2. Learn gui framework
  3. Come back with questions regarding that framework
gnight
  • 429
  • 2
  • 10