2013-01-19 5 views
8

私は、オブジェクトがインスタンス化された場所を実行時に調べようとしています。これは、私のライブラリのユーザに非常に有用なエラーメッセージを提供することを可能にするからです。オブジェクトがインスタンス化された場所を知るにはどうすればよいですか?

は、私たちが次のコードがあるとします。

import mylib 

obj = mylib.MyClass() 

objを、その後mylibから別のクラスのインスタンスに渡され、そして素晴らしい旅に進行されます。どこかの行に沿って、objは何か悪いことが起こります。私はobjがインスタンス化された場所をユーザーに指摘したいと思います。

inspectモジュールを使用して、どのファイルでどの回線番号objがインスタンス化されているかを調べることができました。残念ながら、inspect.getsourcefileinspect.getsourcelinesはインスタンスをサポートしていません。これがサポートされていない技術的な理由はありますか?

私が探しているデータを取得する別の方法はありますか?

+0

はそれほど複雑ではありませんか?何か悪いことが起きたとき、私たち全員が(おそらく)何をするのでしょうか? import traceback + try:... except:traceback.print_exc() – StefanNch

答えて

8

あなたは、クラスのコンストラクタで、この情報を記録することができます:

import traceback 

class MyClass(object): 
    def __init__(self): 
     self.traceback = traceback.extract_stack()[-2] 

obj = MyClass() 

print 'Instantiated in {0}:{1}'.format(*obj.traceback) 
+0

優れています!私はPythonが私を失望させないことを知っていた。 –

+0

残念ながら、継承の各レベルは新しいスタックフレームであり、関係するすべてのオブジェクトに対して一定ではない可能性があるため、これはサブクラスではあまりうまく機能しません。したがって、戻されるフレーム数を決定する余分なロジックが必要になることがあります。複数の継承が関係する場合、これはさらに複雑になります。 – meowsqueak

0

あなたがこれを望むこともできます?

In [1]: def checkinstance(prohibitedclass): 
    ...:  import sys 
    ...:  final_result=set() 
    ...:  for x in sys._getframe(1).f_locals: 
    ...:   if isinstance(sys._getframe(1).f_locals.get(x),prohibitedclass): 
    ...:    final_str="instance of class %s is at: %s"%(prohibitedclass,sys._getframe(1).f_locals.get(x)) 
    ...:    final_result.add(final_str) 
    ...:  return list(final_result) 

In [2]: class not_allowedclass(object): 
    ...:  pass 

In [3]: checkinstance(not_allowedclass) 
Out[3]: [] 

In [4]: nk=not_allowedclass() 

In [5]: nk1=not_allowedclass() 

In [6]: checkinstance(not_allowedclass) 
Out[6]: 
["instance of class <class '__main__.not_allowedclass'> is at: <__main__.not_allowedclass object at 0x102dcdb10>", 
"instance of class <class '__main__.not_allowedclass'> is at: <__main__.not_allowedclass object at 0x102dcda90>"] 

In [7]: nk 
Out[7]: <__main__.not_allowedclass at 0x102dcda90> 

In [8]: nk1 
Out[8]: <__main__.not_allowedclass at 0x102dcdb10> 

In [9]: 
関連する問題