How can I iterate over a list of all classes loaded in memory? I'm thinking of doing it for a backup, looking for all classes inheriting from db.Model (Google App Engine).
Thanks, Neal Walters
How can I iterate over a list of all classes loaded in memory? I'm thinking of doing it for a backup, looking for all classes inheriting from db.Model (Google App Engine).
Thanks, Neal Walters
Classes are defined in modules. Modules are created by an import
statement.
Modules are simply dictionaries. If you want, you can use the dir(x)
function on a module named x
Or you can use x.__dict__
on a module named x
.
In "normal" Python, you can reach all objects via the gc.getobjects()
function of the gc
standard library module; it's then very easy to loop on them, checking which one are classes (rather than instances or anything else -- I do believe you mean instances of classes, but you can very easily get the classes themselves too if that's really what you want), etc.
Unfortunately, the gc
module in App Engine does NOT implement getobjects
-- which makes it extremely difficult to reach ALL classes. For example, a class created by calling:
def makeaclass():
class sic(object): pass
return sic
and hidden into a list somewhere, IS going to be very difficult to reach.
But fortunately, since you say in your question's text that you only care about subclasses of db.Model
, that's even easier than gc
would allow:
for amodel in db.Model.__subclasses__():
...
Just make sure you explicitly ignore such classes you don't care about, such as Expando
;-).
Note that this DOES give you only and exactly the CLASSES, not the instances -- there is no similarly easy shortcut if those are what you're really after!
Based on S.Lott's response: This works if I omit the "if issubclass" except then I get classes I don't want.
import dbModels
self.response.out.write("<br/><br/>Class Names:</br/>")
for item in dbModels.__dict__:
if issubclass(item, db.Model):
self.response.out.write("<br/>" + item)
The above gives error:
TypeError: issubclass() arg 1 must be a class
So it wants a classname as a parm, not an object name apparently.
Based on Alex's answer, this worked great:
self.response.out.write("<br/><br/>Class Names Inheriting from db.Model:</br/>")
for item in db.Model.__subclasses__():
self.response.out.write("<br/>" + item.__name__)
Thanks to both!
Neal