2009-09-17 4 views
2

Как я могу перебирать список всех классов, загруженных в память? Я собираюсь сделать это для резервного копирования, ища все классы, наследующие от db.Model (Google App Engine).Python - Итерация по всем классам

Спасибо, Нил Walters

ответ

9

В «нормальном» Python вы можете достичь всех объектов с помощью функции gc.getobjects() стандартного библиотечного модуля gc; тогда их очень легко зацикливать на них, проверяя, какие из них являются классами (а не экземплярами или чем-то еще). Я полагаю, что вы имеете в виду экземпляров классов, но вы тоже можете сами получить классы сами, если это действительно то, что вы хотите) и т. д.

К сожалению, модуль gc в App Engine НЕ реализует getobjects, что делает его чрезвычайно трудным для достижения ВСЕХ классов. Например, класс, созданный по вызову:

def makeaclass(): 
    class sic(object): pass 
    return sic 

и скрытый в списке где-то, будет очень трудно достать.

Но, к счастью, так как вы говорите, в тексте Вашего вопроса о том, что вы заботитесь только о подклассах db.Model, что еще проще, чем gc позволит:

for amodel in db.Model.__subclasses__(): 
    ... 

Просто убедитесь, что вы явно игнорировать такие классы, которые вы не уход, например, Expando ;-).

Обратите внимание, что это даст вам только и точно КЛАССЫ, не экземпляров - нет так же легко, если ярлык те то, что вы на самом деле после того, как!

+0

Спасибо - см. Мой ответ с кодом. – NealWalters

2

Классы определяются в модулях. Модули создаются оператором import.

Модули - это просто словари. Если вы хотите, вы можете использовать функцию dir(x) на модуле имени x

Или вы можете использовать x.__dict__ на модуле с именем x.

+0

Спасибо - см. Мой ответ с кодом. – NealWalters

0

Основано на ответе С.Лотта: Это работает, если я опускаю «if issubclass», кроме тех случаев, когда я получаю классы, которых я не хочу.

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) 

выше дает ошибку:

TypeError: issubclass() arg 1 must be a class

Так хочет имя класса как Парм, а не имя объекта, по-видимому.

На основании ответа Алекса, это прекрасно работало:

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__) 

Благодаря обоим!

Neal

Смежные вопросы