2011-08-04 22 views
66

私は現在どのクラスの名前を取得していますか?現在のクラスの名前を取得しますか?

例:

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

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

ため、私は(Vistrailsの)とのインタフェース午前のプログラムの性質上、私はinputを初期化するために__init__()を使用することはできません。

答えて

18

クラスの本体内では、クラス名がまだ定義されていないため、使用できません。単純にクラスの名前を入力できませんか?たぶん、あなたが解決策を見つけられるように、問題の詳細を述べる必要があります。

この作業を行うメタクラスを作成します。これはクラス作成時に呼び出され(概念的にはクラスの最後のブロック:ブロック)、作成されるクラスを操作できます。

cls_name = self.__class__.__name__ 

EDIT: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

OK、メタクラスを使用して回答を更新しました。 –

+0

'InputAssigningMetaclass'の' super'行にある 'MyType'は何を指していますか? –

12

:私はこれをテストしていませんクラスのボディでは、それはメソッド内にあります。

99

obj.__class__.__name__はあなたに任意のオブジェクト名を取得しますので、あなたはこれを行うことができます:

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

使用法:

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

これはなぜ受け入れられない答えですか?編集:OK OPのスコープは、クラスレベルでは、内部ではありません。 – KomodoDave

+1

@KomodoDave、これはメソッドのスコープであっても間違っているためです。 子クラスから 'getName'を呼び出すと、子クラス名が出力されます。あなたが本当にあなたが一緒に作業しているクラスをしたい場合は、それはその後トリッキーな取得します。 –

+0

@KenetJervetあなたは_parent_クラスから 'getName'を呼び出すと、子クラス名を出力しますか?それを指摘してくれてありがとう。 – KomodoDave

7

EDIT:はい、できます。現在実行中のクラス名は呼び出しスタックに存在し、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() 
関連する問題