Получить имя текущего класса?

Как мне получить имя класса, в котором я сейчас?

Пример:

def get_input(class_name):
    [do things]
    return class_name_result

class foo():
    input = get_input([class name goes here])

В связи с природой программы я взаимодействую с (vistrails), я не могу использовать __init__() для инициализации input.

Ответ 1

obj.__class__.__name__ получит имя любого объекта, поэтому вы можете сделать это:

class Clazz():
    def getName(self):
        return self.__class__.__name__

Использование:

>>> c = Clazz()
>>> c.getName()
'Clazz'

Ответ 2

Внутри тела класса имя класса еще не определено, поэтому оно недоступно. Не можете ли вы просто ввести имя класса? Возможно, вам нужно больше рассказать о проблеме, чтобы мы могли найти решение для вас.

Я бы создал метакласс для выполнения этой работы для вас. Он вызывается во время создания класса (концептуально в самом конце класса: block) и может манипулировать создаваемым классом. Я не тестировал это:

class InputAssigningMetaclass(type):
    def __new__(cls, name, bases, attrs):
        cls.input = get_input(name)
        return super(MyType, cls).__new__(cls, name, bases, newattrs)

class MyBaseFoo(object):
    __metaclass__ = InputAssigningMetaclass

class foo(MyBaseFoo):
    # etc, no need to create 'input'

class foo2(MyBaseFoo):
    # etc, no need to create 'input'

Ответ 3

Вы можете получить к нему доступ по частным атрибутам класса:

cls_name = self.__class__.__name__

EDIT:

Как сказано в Ned Batcheler, это не будет работать в классе, но это будет в методе.

Ответ 4

РЕДАКТИРОВАТЬ: Да, вы можете; но вы должны обманывать: текущее имя класса присутствует в стеке вызовов, а модуль traceback позволяет получить доступ к стеку.

>>> import traceback
>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> class foo(object):
...      _name = traceback.extract_stack()[-1][2]
...     input = get_input(_name)
... 
>>> 
>>> foo.input
'sbb'

Однако я бы этого не сделал; Мой первоначальный ответ по-прежнему остается моим преимуществом как решение. Оригинальный ответ:

возможно, самым простым решением является использование декоратора, который похож на Ned-ответ, связанный с метаклассами, но менее мощный (декораторы способны к черной магии, но метаклассы способны к древней, оккультной черной магии)

>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> def inputize(cls):
...     cls.input = get_input(cls.__name__)
...     return cls
... 
>>> @inputize
... class foo(object):
...     pass
... 
>>> foo.input
'sbb'
>>> 

Ответ 5

import sys

def class_meta(frame):
    class_context = '__module__' in frame.f_locals
    assert class_context, 'Frame is not a class context'

    module_name = frame.f_locals['__module__']
    class_name = frame.f_code.co_name
    return module_name, class_name

def print_class_path():
    print('%s.%s' % class_meta(sys._getframe(1)))

class MyClass(object):
    print_class_path()