Подтвердить что ты не робот

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. Если они это сделают, я либо конвертирую их во встроенный тип данных, либо удаляю поле с объекта.

4b9b3361

Ответ 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, проверяя большой список имен классов.