【问题标题】:Python type() not giving exact class type instead gives metaclass typePython type() 没有给出确切的类类型,而是给出了元类类型
【发布时间】:2018-12-13 04:48:48
【问题描述】:

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

这是我的课程的样子

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 方法实现我的目标吗?

【问题讨论】:

  • 所以你想要create_obj(Child)?是这样吗?我理解对了吗? (Child.mro()[0]Child。)
  • 是的,我只想这样做,我也可以使用 type(name, bases, dict) 动态创建类,但我更喜欢第一种方法。

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


【解决方案1】:

如果你选择type(Child),你是在问你的Childtype是什么。请记住,类也是 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 的类型是什么instance

您无需执行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'>

【讨论】:

    【解决方案2】:

    一个类是它的元类的一个实例。尔格:

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

    【讨论】:

    • 嗨@wim 感谢您的快速响应,但我不能直接创建 Child() 因为它在实例化我在 create_obj 方法中检索的值时需要很少的强制参数是否有任何其他方法可以实现相同?
    • 将参数传递给create_obj并在调用clzz(...)中使用它们
    • @wim 换句话说:去掉create_obj函数,因为它没用?
    • @Aran-Fey 想必它里面有一些额外的逻辑,或者是从更高的抽象层次使用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    相关资源
    最近更新 更多