Is there a way to call specific classes based on a variable?

Question:

I want a program to call a specific class based on a parameter/variable value. However, I don’t want to use any clunky if-statements. My first thought was to use the globals() function, but I couldn’t get it to work. Here’s an example:

class SomeClass:
    def __init__():
        print("Hello, world!")

class OtherClass:
    def runClass(className):
        # Call class based on variable className

The reason I want to do this is because there is a wide variety of classes may need to be called, and so just piling up if-statements in my code won’t do it. Any help would be greatly appreciated. Thanks!

Asked By: Dominic Miller

||

Answers:

Use a dict.

name_to_class = dict(some=SomeClass,
                     other=OtherClass)

def factory(name):
    klass = name_to_class(name)
    return klass()

some_obj = factory("some")
other_obj = factory("other")
Answered By: J_H

One approach you could try is using the built-in getattr() function, which can be used to get the attribute of an object by its name (as a string). In your case, you could use it to get a reference to the class object based on the value of className, and then you can create an instance of the class and call its methods. Here’s an example:

class SomeClass:
    def __init__(self):
        print("Hello, world!")

class OtherClass:
    def runClass(self, className):
        # Get the class object based on the value of className
        cls = getattr(sys.modules[__name__], className)

        # Create an instance of the class and call its __init__ method
        instance = cls()
        instance.__init__()

# Create an instance of OtherClass and call the runClass method
other = OtherClass()
other.runClass("SomeClass")

Answered By: Paulo Marcelo

One way to solve this problem is to use a dictionary to map the values of the variable className to the corresponding class.

Try this exemple :
class SomeClass:
def init(self):
print("Hello, world!")

class OtherClass:
def init(self):
print("Goodbye, world!")

classNameToClass = {
"SomeClass": SomeClass,
"OtherClass": OtherClass
}

def runClass(className):
# Call class based on variable className
cls = classNameToClass[className]
return cls()

runClass("SomeClass") # prints "Hello, world!"
runClass("OtherClass") # prints "Goodbye, world!"

Here, the dictionary classNameToClass maps the string names of the classes (e.g. "SomeClass") to the corresponding class objects (e.g. SomeClass). Then, in the runClass function, we look up the class object using the value of the className variable, and call it to create an instance of the class.

Answered By: Black_WillyWonka
class MyClass:
    def __init__(self, name):
        self.name = name

def my_factory(name):
    return MyClass(name)

# Create a dictionary that maps class names to their respective classes
classes = {
    'MyClass': MyClass
}

# Get the class name from a parameter/variable value
class_name = 'MyClass'

# Create an instance of the class using the dictionary
instance = classes[class_name]('My Name')

# Print the name
print(instance.name)  # Output: My Name
Answered By: Lucas Fernandes

I’ve found an answer. The parameter that governs the called class can just be assigned elsewhere. At first, I thought it would need some complex function, but in reality, I guess the question didn’t give enough details. The class itself only uses items from whatever object is given. So, instead of having to dynamically call a class, it’s as simple as:

class SomeClass:
    def printHelloWorld():
        print("Hello, world!")

class OtherClass:
    def __init__(self, usingClass):
        self.object = usingClass

    def doThis():
        usingClass.printHelloWorld()

x = OtherClass(SomeClass())
x.doThis()

It’s on me for not giving enough information. Thank you all for your help.

Answered By: Dominic Miller

Here’s how you can call a class via globals

class SomeClass:
    def __init__(self):
        print("Hello, world!")

    def __call__(self):
        return "SomeClass called"

class OtherClass:
    def runClass(self, className):
        globals()[className]()()
        
o = OtherClass()
result = o.runClass("SomeClass")
print(result)

Notice, I am instantiating and then calling it via the __call__ special method, which is the closest match to your description I could think of.

Answered By: tdelaney
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.