Python - проверяет, является ли объект экземпляром любого класса из определенного модуля
Нужен способ проверить, является ли объект экземпляром какого-либо класса в определенном модуле.
Я знаю, что могу сделать это, явно импортируя каждый класс из этого модуля и проверяя с помощью кортежа:
from my_module import ClassOne, ClassTwo
>>> isinstance(my_obj, (ClassOne, ClassTwo))
True
Но на самом деле модуль, в который я импортирую, имеет TON классов в нем, и кажется излишне подробным, чтобы импортировать их все явно, использовать их для создания огромного кортежа и проверять тип на него. Я попробовал несколько вещей, чтобы избежать этого:
import my_module
# Test my_obj against the module itself
>>> isinstance(my_obj, my_module)
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
# Try to test against a wildcard attribute on my_module
>>> isinstance(my_obj, my_module.*)
SyntaxError: invalid syntax
#Try to build a tuple of clases with iteration to check against
>>> for klass in my_module:
TypeError: 'module' object is not iterable
Есть ли способ набрать проверку для ВСЕХ классов в my_module без явного называния их в кортеж?
Дополнительная справочная информация:
Я, возможно, не замечаю лучшего способа подойти к моей проблеме - если вам интересно, вот ситуация:
Мы экспортируем данные из приложения Google App Engine в приложение, которое мы разместили в Rackspace. Мы сериализуем данные с помощью pickle
, а затем отправляем их на наш сервер Rackspace с запросами HTTP.
Некоторые данные в базе данных Google App Engine относятся к типам данных, специфичным для GAE, импортированным из google.appengine.api.datastore_types. Если какой-либо из этих типов данных перейдет через провод к нашему серверу Rackspace, они вызовут ошибку, потому что наше приложение Rackspace не имеет необходимых библиотек GAE. Итак, по пути из GAE, я проверяю, есть ли у какого-либо из исходящих объектов тип из google.appengine.api.datastore_types. Если они это сделают, я либо конвертирую их во встроенный тип данных, либо удаляю поле с объекта.
Ответы
Ответ 1
Вы можете использовать inspect.getmembers
, чтобы получить все классы в вашем модуле:
inspect.getmembers(my_module,inspect.isclass)
Это вернет список пар имя-класс. Вам просто нужны классы:
my_module_classes = tuple(x[1] for x in inspect.getmembers(my_module,inspect.isclass))
Одна вещь, которую мне удалось упустить, когда я изначально написал этот ответ, - это возможность проверить атрибут class __module__
. Возможно, вам удастся избежать проверки того, что __module__
- это то, что вы ожидаете от него:
from somewhere import module
if getattr(obj, '__module__', None) == module.__name__:
# obj is from module.
Это, вероятно, будет дешевле, чем isinstance
, проверяя большой список имен классов.