需要一种方法来检查对象是否是某个特定模块中任何类的实例。
我知道我可以通过显式导入该模块中的每个类并使用元组检查来实现:
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
序列化数据,然后使用HTTP请求将其发送到我们的Rackspace服务器。
Google App Engine数据库中的部分数据属于GAE特定的数据类型,从google.appengine.api.datastore_types导入。如果这些数据类型中的任何一种都通过线路连接到我们的Rackspace服务器,它们将引发错误消除,因为我们的Rackspace应用程序没有所需的GAE库。因此,在离开GAE的路上,我正在检查是否有任何传出对象都有来自google.appengine.api.datastore_types的类型。如果他们这样做,我要么将它们转换为内置数据类型,要么删除该对象的字段。
答案 0 :(得分:12)
您可以使用inspect.getmembers
获取模块中的所有课程:
inspect.getmembers(my_module,inspect.isclass)
这将返回一个名称 - 类对的列表。你只需要这些课程:
my_module_classes = tuple(x[1] for x in inspect.getmembers(my_module,inspect.isclass))
当我最初写这个答案时,我设法忽略的一件事是能够检查一个类的__module__
属性。您可以自行检查__module__
是否符合预期:
from somewhere import module
if getattr(obj, '__module__', None) == module.__name__:
# obj is from module.
这可能比isinstance
检查大量的类名更便宜。
答案 1 :(得分:1)
我使用了@mgilson简单解决方案:
from somewhere import module
if getattr(obj, '__module__', None) == module.__name__:
# obj is from module.
并注意到,如果您有一棵模块树,并且要确保它来自基本模块,则必须执行以下操作:
from somewhere import module
if getattr(obj, '__module__', None).split('.')[0] == module.__name__:
# obj is from module.
但是,如果您的object
来自内置,则会出现异常,所以我会:
from somewhere import module
module_tree = getattr(obj, '__module__', None)
parent = module_tree.split('.')[0] if module_tree else None
if parent == module.__name__:
# obj is from module.