Python type()没有给出确切的类类型而是给出了元类类型

时间:2018-07-04 17:52:51

标签: python inheritance metaclass method-resolution-order six

我正在尝试将类的类型传递给方法,以便可以动态实例化它。该类扩展为基类,而基类进一步扩展为抽象类。现在,当我检查类的类型时,它是抽象类类型,而不是子类。

这是我的班级样子

class AMeta(type):
     # stuff

class Parent(six.with_metaclass(AMeta, object)):
     # stuff

class Child(Parent):
    # stuff

现在,当我使用type(Child) or Child.__class__时,它会给我AMeta,而我想得到Child。我想将此Child传递给可以动态创建其对象的另一种方法。

def create_obj(clzz):
   return clzz()

当我调用create_obj(type(Child))之类的方法时,它不起作用并中断,但是当我调用Child.mro()[0]时,它可以正常工作,这里发生的事情,还有另一种方法可以通过mro实现方法?

2 个答案:

答案 0 :(得分:4)

类是其元类的实例。因此:

  • Child的类型为AMeta
  • Child()的类型为Child

答案 1 :(得分:2)

如果您进行type(Child),则是在问type 中的Child。请记住,类在Python中也是实例。当您在脚本中执行class Child...时,会在脚本的命名空间中添加一个新名称(Child)(几乎是一个Child类型的名为AMeta的变量,因为您重新指定AMetaChild的元类。否则,它的类型将是type,有点像“默认”元类)

请参阅:

import six

class AMeta(type):
     pass

class Parent(six.with_metaclass(AMeta, object)):
     pass

class Child(Parent):
    pass

print(type(Child))
c=Child()
print(type(c))

在第一张纸上,您得到<class '__main__.AMeta'>是因为您在问我的孩子实例是什么类型?。在第二张纸上,您得到<class '__main__.Child'>是因为您正在问我的c 实例是什么类型?

您无需执行type(Child)即可上课。您可以直接使用它。例如:

obj = Child
dynamic_instance = obj()
print(type(dynamic_instance))

将打印<class '__main__.Child'>

更接近您的示例是:

def create_obj(clzz):
   return clzz()

a = create_obj(Child)
print("Just created: %s" % type(a))

哪个输出Just created: <class '__main__.Child'>