How to iterate over every class declaration originating from a specific base class?

I wandered how the elixir \ sqlalchemy recognizes all the entity classes that I declared in my model when I call setup_all() ? I need this functionality in a small project, but I have no idea. I tried steptrace through elixir setup_all() , and I found that it stores a collection of all entity classes in a "global" list (or was it a dict?), But I can not catch the moment when the list is full. Any ideas?

+4
source share
2 answers

Answering the main question without binding SQLALchemy or an elixir at all - yes, this is possible in Python.

The garbage collector ( gc ) module in the standard library has a function call that allows you to retrieve all references to this object, a wide interpreter. The class is always mentioned in the __mro__ attribute of any inherited classes.

Thus, the following function can retrieve all classes that inherit from this class:

 import gc def find_subclasses(cls): all_refs = gc.get_referrers(cls) results = [] for obj in all_refs: # __mro__ attributes are tuples # and if a tuple is found here, the given class is one of its members if (isinstance(obj, tuple) and # check if the found tuple is the __mro__ attribute of a class getattr(obj[0], "__mro__", None) is obj): results.append(obj[0]) return results 
+4
source

It is easier to define classes (no import)

 def find_subclasses(cls): results = [] for sc in cls.__subclasses__(): results.append(sc) return results 

I'm not sure if you want this or objects. If you want objects:

 import gc def find_subclasses(cls): results = [] for sc in cls.__subclasses__(): for obj in gc.get_objects(): if isinstance(obj, sc): results.append(obj) return results 
+9
source

Source: https://habr.com/ru/post/1392257/


All Articles