有没有办法识别类和对象

时间:2011-08-08 06:10:36

标签: python django

例如我有课

Class Cls:
   var 1 
   var 2

   def func(self):
      --- do some statement

现在,我可以简单地导入类并创建对象

import Cls
clsObj = Cls()

这里,Cls是类,clsObj是类的实例。有什么方法可以区分它们。

谢谢

4 个答案:

答案 0 :(得分:3)

认为这会考虑所有情况:

def isclass(obj):
    try:
        class_ = obj.__class__
    except AttributeError:
        # It's an old-style class
        return True
    try:
        class_.__class__
    except AttributeError:
        # It's an old-style instance
        return False
    # It's new-style
    return isinstance(obj, type)

现在让我们测试它以确保它按预期/预期工作:

def test():
    class OldStyle: pass

    class NewStyle(object): pass

    def class_factory():
        return type("DynamicClass", (object,), {})

    class MetaClass(type):
        def __new__(mcls, *args):
            if args:
                return type(*args)
            return class_factory()

    class WithMeta(object):
        __metaclass__ = MetaClass
        def __call__(self):
            return self

    confusing = WithMeta()

    for name, obj in locals().items():
        templ = "{0:>26s} == {1!r:>5}, {2:>26s} == {3!r:>5}"
        print templ.format(
            "isclass({0})".format(name), isclass(obj),
            "isclass({0}())".format(name), isclass(obj()))

输出:

         isclass(OldStyle) ==  True,        isclass(OldStyle()) == False
         isclass(NewStyle) ==  True,        isclass(NewStyle()) == False
         isclass(WithMeta) ==  True,        isclass(WithMeta()) == False
        isclass(MetaClass) ==  True,       isclass(MetaClass()) ==  True
    isclass(class_factory) == False,   isclass(class_factory()) ==  True
        isclass(confusing) == False,       isclass(confusing()) == False

MetaClassclass_factoryconfusing说明在python中构成类的内容是有争议的,并显示了isclass函数如何处理这些情况。

Re:agf

MetaClass并不意味着像那样被实例化,所以你避免错误的技巧实际上只是混淆了这个问题;打印MetaClass()的“错误”会更正确。

你或我写过MetaClass吗?我的意思是要像那样实例化。我会告诉你,每次调用时创建“同一个”类的元类(或类工厂函数)都没什么意义,当然这让人很困惑。但是,出于这些特定目的,我想说明元类在实例化时创建一个类,并且有许多MetaClass()的参数将是输出中的组合断层器。 :)所以原则上我同意你的意见,但是为了这个特定的目的,我这样做,而python允许我这样做。

__call____new__之前发生,因此WithMeta()confusingconfusing()显示正确无误。

如果你通过“发生”意味着“被解析,编译和绑定”然后是,那么首先发生。我不确定我明白你在这里得到了什么。我同意它是正确的 - 当然它是正确的,这个代码是编写和运行的,我发布了我得到的结果,所以它不能不正确。我没有看到__call__与它有什么关系。你能详细说明一下吗?

您实际上从未实例化WithMeta。您应该删除__call__并显示confusing()

的错误

我很确定我实例化WithMeta

>>> WithMeta()
<isclass.WithMeta object at 0xb784574c>

当我写WithMeta()时,python将检查是否定义了type(WithMeta).__new__,并且它是,所以python然后提供类名,基和命名空间dict作为MetaClass.__new__()的参数。它返回WithMeta类对象,该对象通过使用相同的参数调用type来生成。

另一方面,confusing()type(confusing).__dict__["__call__"](confusing)相同,后者只返回参数,因此confusing == confusing()

答案 1 :(得分:2)

是的,只需使用内置类型(),它提供特定对象的类型。 type(clsObj)将Instance作为答案。您也可以查看isinstance isinstance(clsObj,Cls)将返回True,而isinstance(Cls,Cls)将返回False

答案 2 :(得分:1)

我不明白你为什么需要,但你可以这样做:

if type(obj) == type:
    # It's a class.
else:
    # It's an instance of a class.

答案 3 :(得分:1)

您可以使用属性__class__ - clsObj.__class__

来自python tutorial

  

每个值都是一个对象,因此有一个类(也称为它   类型)。它存储为object.__class__