I'm working on a project which due to the complexity of the business logic has had to pull out some classes to do computation related to some values in a database. To link the code and database, both when inserting and selecting, I need to get a list of all the class names contained within a single file. It works for me, but is this a sane approach?
import inspect
import my_module
my_module_class_names = [
name for name, clazz in inspect.getmembers(my_module, inspect.isclass)
if clazz.__module__ == my_module.__name__
]
inspect.getmembers(my_module, inspect.isclass)
gets any class members ofmy_module
.if clazz.__module__ == my_module.__name__
ensures that classesimport
ed intomy_module
are excluded from the list. This is the main reason I'm asking for a review - I only thought to include this clause because I had alreadyimport
ed other classes, and therefore the list had extraneous members.
Alternatively, from within my_module
:
import inspect
import sys
def class_names() -> List[str]:
return [
name for name, clazz in inspect.getmembers(sys.modules[__name__], inspect.isclass)
if clazz.__module__ == sys.modules[__name__].__name__
]
1 Answer 1
I have already used similar code and it looks rather fine. Some nitpicks:
- I’d name the variable
cls
to mimic the name often used as first parameters of@classmethod
s; orclass_
as it is more common; - I’d store a list of classes intead of a list of names, this feels more directly usable (and names are still stored as
cls.__name__
if need be); sys.modules[__name__].__name__
should be just__name__
.
Alternatively, since these classes seems related to each other, you may have an inheritance tree; or maybe a common base class. In this case, you could be even more specific using something such as:
[cls for _, cls in inspect.getmembers(my_module, inspect.isclass) if issubclass(cls, my_module.CommonBase)]
or
my_module.CommonBase.__subclasses__()
if there really is a single level of inheritance, but I wouldn't count much on it as it can break so easily.
-
\$\begingroup\$ Excellent! I do need the actual class names rather than the
type
s, and I don't have a class hierarchy, but this can serve as basically a recipe for anyone who wants either variant of this pattern. \$\endgroup\$l0b0– l0b02019年01月10日 18:51:43 +00:00Commented Jan 10, 2019 at 18:51
Explore related questions
See similar questions with these tags.