2016-06-27 7 views
0

引数を持つクラスデコレータを作成しました。このデコレータは、クラスフィールドIDの値を設定する必要があります。私は、次の方法でそれをやっている:クラスデコレータ - クラスフィールドの変更によってベースクラスの値が変更される

が機能 createTest
class Base: 
    ID = "ID_Base" 
    def __init__(self, n): 
     self.n = n 

    def func(self): 
     pass 

def Test(cnt): 
    def createTest(className): 
     class _Test(className): 
      def __init__(self, n): 
       className.__init__(self, n) 

      def func(self): 
       for n in range(cnt): 
        className.func(self) 

     name = className.__name__ + "_Test" 
     _Test.__name__ = name 
     globals()[name] = _Test 

     _Test.ID = className.ID + '_test' 
     className.ID = '' 
     return _Test 

    return createTest 

@Test(2) 
class Derived(Base): 
    pass 

print(Base.ID) 
print(Derived.ID) 
print(Derived_Test.ID) 

が最初に私は、私はその後、新しい_Testクラスのクラス名を変更し、現在のモジュールのグローバルクラスとして登録、指定されたクラス型から派生したクラスの定義を持っています(最後のブロック)ID属性を_Testクラスに設定し、クラス内のIDクラスをパラメータとして渡してクリアし、新しいタイプを返します。それは代わりにデコレータで作成し_TestDerivedクラスの属性を変更するのはなぜ

ID_Base 
ID_Base_test 
ID_Base_test 

:私はこれを見たが、それを実行した後

ID_Base 

ID_Base_test 

:私は、次のような結果を得るためにこれをしませんでしたか?それを修正する方法は?

Python 2.6.6(Linux)とPython 3.4.1(WindowsのActivePython)を使用してこれをチェックしました。

編集:私はまた、以下のような_Testクラス内のIDを設定しようとしましたが、同じ結果を得た:

def Test(cnt): 
    def createTest(className): 
     class _Test(className): 
      ID = className.ID + '_test' 
+0

Derived_Testはどこから来ていますか?彼は注釈も持っていますか? –

+0

Derived_Testの名前はデコレータ、特に次の行に作成されます: 'name = className .__ name__ +" _Test "''_Test .__ name__ = name' ' globals()[name] = _Test' –

答えて

2

あなたはprint(Derived.ID)からID_Base_testを得た理由は、の最後に暗黙の割り当てがあるということです装飾することにより、Derivedclass Derived_Testとなります。コード

種類の
@Test(2) 
class Derived(Base): 
    pass 

以下は装飾後print(Derived)を試してみてください

class Derived(Base): 
    pass 
Derived = Test(2)(Derived) 

に等しく、あなたは__main__.Derived_Testを取得します。

更新:詳細はthis wikiを参照してください。

デコレータは、関数、メソッド、またはクラス定義を変更するために使用される任意の呼び出し可能なPythonオブジェクトです。デコレータは定義されている元のオブジェクトに渡され、変更されたオブジェクトが返され、次に定義の名前にバインドされます。

+0

ありがとう、意味あり。 –

関連する問題