Получение имени класса, который имеет мета класс - PullRequest
0 голосов
/ 02 января 2019

Предположим, я определяю класс A с мета-классом, например так:

class Meta(type):
    pass

class A(metaclass=Meta):
    pass

Затем, когда я пытаюсь получить доступ к имени класса A, я получаю имя мета-класса:

A.__class__.__name__
#  'Meta'

Однако, разве это не должно дать мне A, мой определенный класс?

Примечание: Я пытался использовать A.__mro__[0].__name__, и это даетменя A, но я все еще не понимаю, почему A.__class__ дает мне имя мета-класса.У кого-нибудь есть объяснение этому?

Ответы [ 2 ]

0 голосов
/ 03 января 2019

A уже является классом - его имя под A.__name__. Если вы попробуете A.__class__.__name__, вы попадете в класс, к которому A относится экземпляр (то есть его метакласс), name.

A.__mro__[0].__name__ будет следовать «порядку разрешения метода» для класса A - объект __mro__ является кортежем со всей иерархией классов, которая начинается в самом определенном классе и заканчивается в object. Таким образом, A.__mro__[0] всегда будет A сам по себе - и A.__mro__[0].__name__ совпадает с A.__name__.

Атрибуты __name__ и __qualname__ являются записываемыми атрибутами: например, изменение {__qualname__ после создания класса изменит значение по умолчанию __repr__ для экземпляров этого класса. Хотя они находятся в определении языка и «живут» в слотах класса (не в его словаре), возможно создать свойство __name__ (я имею в виду, встроенное property) объект или любой другой дескриптор) в метаклассе, который будет динамически изменять атрибут __name__ класса (но не __qualname__ - это должен быть атрибут класса и строка)

0 голосов
/ 02 января 2019

__class__ dunder сообщает:

класс, к которому принадлежит экземпляр класса.

Цитата из instance.__class__

class A принадлежит классу его метакласса - только экземпляры A принадлежат самому классу A.

a = A() 
print(a.__class__.__name__) # 'A' 
print(A.__class__.__name__) # 'Meta'

class P: pass 

print(P.__class__.__name__) # type 
print(P().__class__.__name__) # P

Чтобы получить имя самого класса, просто используйте

A.__name__

, если вам это действительно нужно.


Я все еще могу получить от ответа до Что такое метаклассы в Python? - может быть, это поможет вам.

...