Python type () не дает точный тип класса, а дает тип метакласса - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь передать тип класса методу, чтобы он мог быть динамически создан. Класс распространяется на базовый класс, который далее распространяется на абстрактный класс. Теперь, когда я проверяю тип моего класса, он становится абстрактным типом класса, а не дочерним.

Вот как выглядят мои уроки

class AMeta(type):
     # stuff

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

class Child(Parent):
    # stuff

Теперь, когда я использую type(Child) or Child.__class__, это дает мне AMeta, тогда как я хотел бы получить Child. Я хочу передать этого потомка другому методу, который бы динамически создавал свой объект.

def create_obj(clzz):
   return clzz()

Когда я вызываю метод наподобие create_obj(type(Child)), он не работает и ломается, но когда я вызываю Child.mro()[0], он прекрасно работает, что здесь происходит, и есть ли другой способ достичь того, чего я достигаю с помощью метода mro?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Если вы делаете type(Child), вы спрашиваете, что такое type вашего Child класса . Помните, что классы также являются экземплярами в Python. Когда в вашем скрипте вы делаете class Child..., в пространство имен скрипта добавляется новое имя (Child) (в значительной степени переменная с именем Child типа AMeta, так как вы указываете, что AMeta является метакласс Child. В противном случае он будет иметь тип 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'>, потому что вы спрашиваете Каков тип моего Child instance ? . Во втором отпечатке вы получите <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'>

0 голосов
/ 04 июля 2018

Класс является экземпляром своего метакласса. Ergo:

  • Тип Child равен AMeta
  • Тип Child() равен Child
...