パッケージ構造を次のように考えてみましょう。
myApp
|-- myPackage
| |-- __init__.py
| +-- myModule.py
|-- __init__.py
+-- main.py
myModule.py には、次のような単一のクラスが含まれています。
class MyClass( object ):
_myList = []
@classmethod
def test( cls ):
cls._myList.append( len( cls._myList ) )
return cls._myList
def __init__( self ):
return
pass
ご覧のとおり、特別なことは何もありません。リストを静的クラス変数として定義しているだけです。次に、main.py のコードを考えてみましょう。
from myApp.myPackage.myModule import MyClass as MyClassAbs
from myPackage.myModule import MyClass as MyClassRel
if __name__ == '__main__':
print '\n myList'
print 'MyClassAbs().test():', MyClassAbs().test() #< Prints [0].
print 'MyClassRel().test():', MyClassRel().test() #< Prints [0] but should be [0, 1].
print 'MyClassAbs.test():', MyClassAbs.test() #< Prints [0, 1] but should be [0, 1, 2].
print 'MyClassRel.test():', MyClassRel.test() #< Prints [0, 1] but should be [0, 1, 2, 3].
print '\n myList ids'
print id( MyClassAbs().test() )
print id( MyClassRel().test() )
print id( MyClassAbs.test() )
print id( MyClassRel.test() )
print ''
print 'MyClassAbs == MyClassRel:', MyClassAbs == MyClassRel #< Prints False
print 'isinstance( MyClassAbs(), MyClassRel ):', isinstance( MyClassAbs(), MyClassRel ) #< Prints False
print 'isinstance( MyClassRel(), MyClassAbs ):', isinstance( MyClassRel(), MyClassAbs ) #< Prints False
pass
問題は、私のコードでは、同じモジュールから同じクラスを 2 回インポートしていますが、異なる方法でインポートしていることです。1 回は絶対インポートとして、もう 1 回は相対インポートとしてインポートしています。コードの最後の部分に見られるように、クラスが同じであっても、それらのモジュールは sys.modules に個別に登録されているため、クラスは等しくありません。
'myApp.myPackage.myModule': <module 'myApp.myPackage.myModule' from '/full/path/myApp/myPackage/myModule.py'>
'myPackage.myModule': <module 'myPackage.myModule' from '/full/path/myApp/myPackage/myModule.py'>
その結果、それらの表現は異なります。
'MyClassAbs': <class 'myApp.myPackage.myModule.MyClass'>
'MyClassRel': <class 'myPackage.myModule.MyClass'>
それで...この変数を静的に設定する方法はありますか?
編集:
上記のコードは、明らかに私の実際の問題を縮小したものにすぎません。実際には、基本的に、フォルダー内に再帰的にネストされたすべてのモジュールを検査し、そこに含まれるクラスを登録するコードがあります。この方法で登録されたすべてのクラスは、次のような共通の構文を使用してインスタンス化できます。
myApp.create( 'myClass' )
これが、同じクラスを指しているが異なる方法でインポートされた 2 つのオブジェクトを持つことがある理由です。1 つは imp.load_module() 呼び出しによって自動的にインポートされ、もう 1 つは従来の import ステートメントによってユーザーによって直接インポートされます。ユーザーがクラスを手動でインポートすることにした場合でも、自動的に登録された同じクラス内で定義された変数と同じ静的クラス変数にアクセスできる必要があります。それが理にかなっていると思いますか?