Convert string to Python class object?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Converting a string to a Python class object is really a lookup problem. The safe solution depends on where the class lives and how dynamic you want the system to be. In most cases, a registry or getattr on a known module is better than using eval.
Use an Explicit Registry When You Control the Classes
If the valid class names are known in advance, define a mapping from string to class:
This is usually the best design because it is explicit, easy to validate, and safe for untrusted input.
Use getattr for Known Modules
If the class name comes from a module you control, import the module and look up the attribute:
This is more dynamic than a registry, but it still stays inside a known namespace.
Avoid eval for This Job
You may see examples like:
This is usually the wrong approach. eval executes arbitrary expressions, which makes it unsafe for untrusted input and harder to reason about than a controlled lookup.
A registry or getattr expresses the intent more clearly and limits what names can be resolved.
Validate Before Instantiating
Once you have the class object, you may want to instantiate it:
But before doing that, it is often worth checking that the resolved object is actually the kind of class you expect. In plugin systems, for example, you may want to enforce inheritance from a base class or the presence of required methods.
Choose the Lookup Strategy by Trust Level
A practical rule is:
- use a registry for trusted explicit choices
- use
getattron a known module for dynamic plugin-style lookup - avoid
evalunless you are solving a very unusual controlled case
The less open-ended the lookup needs to be, the easier it is to secure and maintain.
Dynamic Lookup Should Still Be Bounded
Even when the system is dynamic, define the namespace or registry that the lookup is allowed to search. Controlled flexibility is far easier to secure and debug than open-ended string execution.
Common Pitfalls
- Using
evalwhen a dictionary orgetattrwould be safer and clearer. - Looking in
globals()and assuming the class is always present there. - Importing arbitrary module paths from untrusted input.
- Instantiating the looked-up object before checking that it is the right class type.
- Treating dynamic class lookup as magic instead of as a controlled namespace resolution problem.
Registries Also Improve Error Messages
When lookup goes through an explicit registry, you can return clearer errors such as which names are supported. That is another reason registries are often better than open-ended dynamic execution.
Dynamic Loading Still Needs a Trust Boundary
Even in plugin systems, decide which modules and class names are allowed before loading them. That one boundary decision does most of the work in keeping dynamic class lookup practical and safe.
Summary
- Turning a string into a class object is usually a lookup operation, not a conversion trick.
- A registry dictionary is the safest and clearest option when the valid classes are known.
- '
getattrwithimportlibworks well for controlled dynamic loading.' - '
evalis usually the wrong tool because it is too open and too risky.' - Validate the resolved class before instantiating it in plugin-style systems.

