Получение имени класса экземпляра?
Как узнать имя класса, который создал экземпляр объекта в Python, если функция, из которой я делаю это, является базовым классом, из которого был получен класс экземпляра?
Думал, может быть, модуль проверки может иметь помог мне здесь, но это не дает мне то, что я хочу. И если не считать синтаксического анализа члена __class__ , я не уверен, как получить эту информацию.
8 ответов
Вы пробовали атрибут __name__ класса? то есть type(x).__name__ даст вам имя класса, который, я думаю, вам нужен.
Этот метод работает только с классами нового стиля. Ваш код может использовать классы старого стиля. Следующее работает для обоих:
В качестве альтернативы вы можете использовать декоратор classmethod :
Вы хотите имя класса в виде строки?
Вот простой пример, основанный на GHZ, который может кому-то помочь:
Помимо захвата специального __name__ атрибута, вы может понадобиться квалифицированное имя для данного класса / функции. Это делается путем захвата типов __qualname__ .
В большинстве случаев они будут точно такими же, но при работе с вложенными классами / методами они отличаются в выводе, который вы получаете. Например:
Поскольку вам нужен самонаблюдение, вы всегда можете об этом подумать.
Приведенный выше пример кода (при вводе в интерактивном интерпретаторе) будет производить ‘__main__.A’ , а не ‘A’ , который создается, если вызывается атрибут __name__ . Просто передавая результат A.__class__ в конструктор str , анализ обрабатывается для вас. Тем не менее, вы также можете использовать следующий код, если вы хотите что-то более явное.
Такое поведение может быть предпочтительным, если у вас есть классы с одинаковыми именами, определенные в отдельных модулях.
Приведенный выше пример кода был протестирован в Python 2.7.5.
Узнать имя класса во время исполнения программы
У меня есть функция (используется для записи логов), которая вызывается в разных классах. Не хочется каждый раз переписывать код в ней для каждого нового класса(они будут и добавляться и убираться со временем, ну или вообще функция будет использоваться в дальнейшем в других проектах).
Мне хотелось бы узнавать имя класса, из которого она вызывается (для задания имени файлу и прочих плюшек) не передавая лишних параметров в функцию.
Это можно реализовать? Можно и boost`ом.
Функция typeid(object) возвращает объект типа type_info с информацией о типе объекта, для которого она вызывается (собственно, о классе). У этого объекта( type_info ) есть метод name() , который и возвращает имя класса. Для использования нужно подключить <typeinfo> .
Так что в итоге для получения имени класса нужно использовать
Или, если функция не является методом класса, передать в typeid сам объект или разыменованный указатель.
![]()
Собственные средства c++ не позволяют ничего узнать о контектсте вызова функции.
Стек вызова можно проанализировать с помощью некоторых внешних библиотек / API операционной системы. Например: http://man7.org/linux/man-pages/man3/backtrace.3.html https://msdn.microsoft.com/en-us/library/ms680650%28VS.85%29.aspx . Но для применение этих средств может налагать дополнительные ограничения на собираемый код (сборка с отладочной информацией и т.д.).
Более разумно, ИМХО, передавать контекст вызова явно: это позволит использовать «штатные» средства c++: __FILE__ , __LINE__ , __func__ , . Извлечение контекста можно замаскировать макросом:
Имя класса можно извлечь либо разобрав имя __FUNCTION__ , либо из указателя this :
Но не хочется включать этот обращение к this в макрос, поскольку функции может быть вызвана из контекста, статической функции.
С другой стороны для целей разделения логов может быть достаточно __FILE__ .
Получение имени класса в Java
Изучите различные способы получения имени класса в Java.
- Автор записи
1. Обзор
В этом уроке мы узнаем о четырех способах извлечения имени класса из методов Class API: getSimpleName () , getName () , getTypeName() и getCanonicalName() .
Эти методы могут сбивать с толку из-за их схожих названий и их несколько расплывчатых Javadoc. Они также имеют некоторые нюансы, когда речь заходит о примитивных типах, типах объектов, внутренних или анонимных классах и массивах.
2. Получение Простого Имени
Давайте начнем с метода getSimpleName () .
В Java существует два типа имен: простые и квалифицированные . Простое имя состоит из уникального идентификатора, в то время как полное имя представляет собой последовательность простых имен, разделенных точками.
Как следует из его названия, getSimpleName() возвращает простое имя базового класса, то есть имя, которое было дано в исходном коде .
Давайте представим себе следующий класс:
Его простое имя будет RetrieveClassName :
Мы также можем получить примитивные типы и массивы простых имен. Для примитивных типов, которые будут просто их именами, например int, boolean или float .
А для массивов метод вернет простое имя типа массива, за которым следует пара открывающих и закрывающих скобок для каждого измерения массива ([]) :
Следовательно, для двумерного String массива вызов getSimpleName() в его классе вернет String[][] .
Наконец, есть конкретный случай анонимных классов. Вызов getSimpleName() в анонимном классе вернет пустую строку.
3. Получение Других Имен
Теперь пришло время взглянуть на то, как мы могли бы получить имя класса, имя типа или каноническое имя. В отличие от getSimpleName() , эти имена предназначены для предоставления дополнительной информации о классе.
Метод getCanonicalName() всегда возвращает каноническое имя , определенное в спецификации языка Java .
Что касается других методов, выходные данные могут немного отличаться в зависимости от вариантов использования. Мы увидим, что это означает для различных типов примитивов и объектов.
3.1. Примитивные типы
Давайте начнем с примитивных типов, поскольку они просты. Для примитивных типов все три метода getName (), getTypeName() и getCanonicalName() вернут тот же результат, что и getSimpleName() :
3.2. Типы объектов
Теперь мы посмотрим, как эти методы работают с типами объектов. Их поведение, как правило, одинаковое: все они возвращают каноническое имя класса .
В большинстве случаев это полное имя, которое содержит все простые имена пакетов классов, а также простое имя класса:
3.3. Внутренние классы
То, что мы видели в предыдущем разделе, – это общее поведение этих вызовов методов, но есть несколько исключений.
Внутренние классы-один из них. Методы getName() и getTypeName() ведут себя иначе, чем метод getCanonicalName() для внутренних классов.
getCanonicalName() по-прежнему возвращает каноническое имя класса , то есть каноническое имя заключающего класса плюс простое имя внутреннего класса, разделенное точкой.
С другой стороны, методы getName() и getTypeName() возвращают почти то же самое, но используют доллар в качестве разделителя между каноническим именем заключающего класса и простым именем внутреннего класса .
Давайте представим себе внутренний класс InnerClass нашего RetrieveClassName :
Затем каждый вызов обозначает внутренний класс немного по-другому:
3.4. Анонимные классы
Анонимные классы-еще одно исключение.
Как мы уже видели, у них нет простого имени, но у них также нет канонического имени . Поэтому getCanonicalName() ничего не возвращает. В отличие от getSimpleName() , getCanonicalName() вернет null | и не пустую строку при вызове анонимного класса.
Что касается getName() и getTypeName () , они вернут каноническое имя вызывающего класса, за которым последуют доллар и число, представляющее положение анонимного класса среди всех анонимных классов, созданных в вызывающем классе .
Давайте проиллюстрируем это на примере. Мы создадим здесь два анонимных класса и вызовем getName() на первом и getTypeName() на втором, объявив их в com.baeldung.Главная :
Следует отметить, что второй вызов возвращает имя с увеличенным числом в конце, поскольку оно применяется ко второму анонимному классу.
3.5. Массивы
Наконец, давайте посмотрим, как массивы обрабатываются вышеперечисленными тремя методами.
Чтобы указать, что мы имеем дело с массивами, каждый метод обновит свой стандартный результат. Методы getTypeName() и getCanonicalName() добавят пары скобок к своему результату.
Давайте рассмотрим следующий пример, в котором мы вызываем getTypeName() и getCanonicalName() для двумерного внутреннего класса массива:
Обратите внимание, как первый вызов использует доллар вместо точки, чтобы отделить внутреннюю часть класса от остальной части имени.
Теперь давайте посмотрим, как работает метод getName () . При вызове массива примитивного типа он возвращает открывающую скобку и букву, представляющую примитивный тип . Давайте проверим это на следующем примере, вызвав этот метод для двумерного массива примитивных целых чисел:
С другой стороны, при вызове массива объектов он добавит открывающую скобку и букву L к своему стандартному результату и завершится точкой с запятой . Давайте попробуем это на массиве RetrieveClassName :
4. Заключение
В этой статье мы рассмотрели четыре метода доступа к имени класса в Java. Эти методы: getSimpleName(), getName(), getTypeName() и getCanonicalName() .
Мы узнали, что первый просто возвращает имя исходного кода класса, в то время как другие предоставляют дополнительную информацию, такую как имя пакета и указание на то, является ли класс внутренним или анонимным классом.