Почему MyClass .__ class__ возвращает значение, отличное от MyClass () .__ class__? - PullRequest
0 голосов
/ 04 июня 2011

Я хочу иметь возможность вызвать person.Person. class и получить обратно classperson.Person, как это делается для объекта person:

>>> p = person.Person()
>>> p.__class__
<class 'person.Person'>
>>> person.Person.__class__
<class 'perframe.datatype.TypeSystemMeta'>

Вот дерево наследования Персона ...

class TypeSystem(object):
    __metaclass__ = TypeSystemMeta    

class Model(TypeSystem):
    pass    

class Node(Vertex,Model):
    pass

class Person(Node):
    pass

Что здесь происходит?

Ответы [ 3 ]

5 голосов
/ 04 июня 2011

В Python даже классы являются объектами, и каждый объект является экземпляром класса. Person относится к «объекту класса», который является экземпляром type. В этом случае в игре есть метакласс - очень запутанная магия метапрограммирования, но если вы хотите введение, см. Что такое метакласс в Python? . Если вы объявляете class Foo(object), Foo.__class__ is type (все по-другому и более запутанно для старой классики, которая не наследуется от объекта). Кстати, это приводит к еще большей странности в том, что type кажется самим собой.

2 голосов
/ 04 июня 2011

Просто используйте ссылку на person.Person:

>>> p = person.Person() 
>>> p.__class__ 
<class 'person.Person'> 
>>> person.Person
<class 'person.Person'> 

Очень полезным ресурсом по системе типов Python является исходный проект системы типов Python для версий 2.2 +.

http://www.python.org/download/releases/2.2/descrintro/

1 голос
/ 04 июня 2011

Чтобы понять, почему вы получаете результат, который вы получили, вы должны понять, что такое метакласс. И чтобы понять это, вы должны понимать, как создаются классы в Python.

Когда вы пишете оператор class, интерпретатор открывает новое пространство имен, выполняет код в операторе и просматривает состояние пространства имен после выполнения этого кода. Затем он обрабатывает важные детали (локальные переменные, имя класса, ...) и передает их встроенному классу type. Поэтому экземпляры type - это то, что мы обычно называем классами, поэтому type - это «метакласс».

Когда вы переопределяете метакласс, вы говорите Python не использовать type для создания нового класса. Вместо этого он передаст те же вещи пользовательскому классу. Это позволяет вам переопределить значения по умолчанию в type.

Таким образом, person.Person был создан путем передачи некоторых аргументов вашему метаклассу. В частности, это экземпляр этого класса, поэтому его __class__ является метаклассом!

...