获取当前类的名称?

问题:获取当前类的名称?

如何获得当前所在Class的名称?

例:

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

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

由于我要与(vistrails)交互的程序的性质,我不能使用__init__()initialize input

How do I get the name of the class I am currently in?

Example:

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

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

Due to the nature of the program I am interfacing with (vistrails), I cannot use __init__() to initialize input.


回答 0

obj.__class__.__name__ 将获得任何对象名称,因此您可以执行以下操作:

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

用法:

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

obj.__class__.__name__ will get you any objects name, so you can do this:

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

Usage:

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

回答 1

在类的主体内,类名尚未定义,因此不可用。您不能简单地输入类的名称吗?也许您需要更多地谈论该问题,以便我们为您找到解决方案。

我将创建一个元类来为您完成这项工作。它是在类创建时调用的(概念上是在类的最后:块),并且可以操纵正在创建的类。我还没有测试过:

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'

Within the body of a class, the class name isn’t defined yet, so it is not available. Can you not simply type the name of the class? Maybe you need to say more about the problem so we can find a solution for you.

I would create a metaclass to do this work for you. It’s invoked at class creation time (conceptually at the very end of the class: block), and can manipulate the class being created. I haven’t tested this:

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'

回答 2

您可以通过类的私有属性来访问它:

cls_name = self.__class__.__name__

编辑:

如所述Ned Batcheler,这在类主体中不起作用,但在方法中将起作用。

You can access it by the class’ private attributes:

cls_name = self.__class__.__name__

EDIT:

As said by Ned Batcheler, this wouldn’t work in the class body, but it would in a method.


回答 3

引入了PEP 3155__qualname__,它是在Python 3.3中实现的。

对于顶级函数和类,该__qualname__属性等于该__name__属性。对于嵌套类,方法和嵌套函数,该__qualname__属性包含一个虚线路径,该虚线路径从模块顶层通向该对象。

可从类或函数的定义中访问它,例如:

class Foo:
    print(__qualname__)

将有效打印Foo。您将获得全限定名称(不包括模块名称),因此您可能希望将其拆分到.字符。

但是,无法获得要定义的类的实际句柄。

>>> class Foo:
...     print('Foo' in globals())
... 
False

PEP 3155 introduced __qualname__, which was implemented in Python 3.3.

For top-level functions and classes, the __qualname__ attribute is equal to the __name__ attribute. For nested classes, methods, and nested functions, the __qualname__ attribute contains a dotted path leading to the object from the module top-level.

It is accessible from within the very definition of a class or a function, so for instance:

class Foo:
    print(__qualname__)

will effectively print Foo. You’ll get the fully qualified name (excluding the module’s name), so you might want to split it on the . character.

However, there is no way to get an actual handle on the class being defined.

>>> class Foo:
...     print('Foo' in globals())
... 
False

回答 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'
>>> 

EDIT: Yes, you can; but you have to cheat: The currently running class name is present on the call stack, and the traceback module allows you to access the stack.

>>> 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'

However, I wouldn’t do this; My original answer is still my own preference as a solution. Original answer:

probably the very simplest solution is to use a decorator, which is similar to Ned’s answer involving metaclasses, but less powerful (decorators are capable of black magic, but metaclasses are capable of ancient, occult black magic)

>>> 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()
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()

回答 6

我认为应该是这样的:

    class foo():
        input = get_input(__qualname__)

I think, it should be like this:

    class foo():
        input = get_input(__qualname__)