2011-08-04 148 views
66

我如何获得我目前所在班级的名字?获取当前课程的名称?

实施例:

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

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

由于我正在与(vistrails)接口的程序的性质,我无法使用__init__()初始化input

回答

18

在类的主体中,类名尚未定义,因此它不可用。你不能简单地输入班级的名字吗?也许你需要更多地说出这个问题,以便我们为你找到解决方案。

我会创建一个元类来为你做这个工作。它在创建类的时候被调用(概念上在类的最后部分),并且可以操作正在创建的类。我没有测试过这一点:

cls_name = self.__class__.__name__ 

编辑:

正如Ned Batcheler说,这是行不通的

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

为了澄清什么,我试图做的:我需要创建和初始化类变量,“输入”,**外的方法**。我有一堆小类,每个小类都必须使用它们的类名称作为参数调用“get_input”。我试图概括这个,所以我不必去每个班级(将会有100个左右)并输入班级名称。 –

+0

好的,我用一个应该帮助的元类更新了我的答案。 –

+0

“InputAssigningMetaclass”中'super'行中的'MyType'是指什么? –

12

你可以通过类的私有属性访问在课堂上,但它会在一个方法。

99

obj.__class__.__name__将让你的任何物体的名字,所以你可以这样做:

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

用法:

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

为什么这不是公认的答案?编辑:好吧OP的范围不是内在的,它是在课堂上的水平。 – KomodoDave

+1

@KomodoDave,因为这是错误的,即使在方法范围内。 当你从一个子类调用'getName'时,它将输出子类的名字。如果你真的想要你正在使用的课程,那么它会变得棘手。 –

+0

@KenetJervet你的意思是当你从_parent_类调用'getName'时,它会输出子类名?好的,指出这一点。 – KomodoDave

7

编辑:是的,你可以;但您必须作弊:当前正在运行的类名称存在于调用堆栈中,并且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' 

但是,我不会这样做;我的原始答案仍然是我自己的偏好,作为解决方案。原来的答复:

可能是非常简单的解决方法是使用一个装饰,它类似于斯内德的回答涉及元类,但不那么强大的(装饰有能力的黑魔法,但元类能够古老,神秘黑魔法)

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