私の目的は、このためにアプリケーションのシーケンス図を刺激することです。実行時に呼び出し元と呼び出し先のクラス名に関する情報が必要です。呼び出し元の関数を正常に取得できますが、呼び出し元のクラス名を取得できませんか?
#Scenario caller.py:
import inspect
class A:
def Apple(self):
print "Hello"
b=B()
b.Bad()
class B:
def Bad(self):
print"dude"
print inspect.stack()
a=A()
a.Apple()
スタックを印刷したとき、呼び出し元クラスに関する情報はありませんでした。それで、実行時に呼び出し元クラスを取得することは可能ですか?
まあ、プロンプトを少し掘り下げた後、ここに私が得るものがあります:
stack = inspect.stack()
the_class = stack[1][0].f_locals["self"].__class__
the_method = stack[1][0].f_code.co_name
print("I was called by {}.{}()".format(str(calling_class), calling_code_name))
# => I was called by A.a()
呼び出されたとき:
➤ python test.py
A.a()
B.b()
I was called by __main__.A.a()
ファイルtest.py
:
import inspect
class A:
def a(self):
print("A.a()")
B().b()
class B:
def b(self):
print("B.b()")
stack = inspect.stack()
the_class = stack[1][0].f_locals["self"].__class__
the_method = stack[1][0].f_code.co_name
print(" I was called by {}.{}()".format(str(the_class), the_method))
A().a()
オブジェクト以外から呼び出されたときの動作がわからない。
Pythonからの回答を使用する:「フレーム」オブジェクトからクラス情報を取得する方法
私はこのようなものを手に入れます...
import inspect
def get_class_from_frame(fr):
args, _, _, value_dict = inspect.getargvalues(fr)
# we check the first parameter for the frame function is
# named 'self'
if len(args) and args[0] == 'self':
# in that case, 'self' will be referenced in value_dict
instance = value_dict.get('self', None)
if instance:
# return its class
return getattr(instance, '__class__', None)
# return None otherwise
return None
class A(object):
def Apple(self):
print "Hello"
b=B()
b.Bad()
class B(object):
def Bad(self):
print"dude"
frame = inspect.stack()[1][0]
print get_class_from_frame(frame)
a=A()
a.Apple()
これは私に次の出力を与えます:
Hello
dude
<class '__main__.A'>
明らかに、これはクラス自体への参照を返します。クラスの名前が必要な場合は、__name__
属性から取得できます。
残念ながら、これはクラスまたは静的メソッドでは機能しません...
おそらくこれはいくつかのPythonプログラミングプロトコルを壊していますが、Badがalwaysで呼び出し元のクラスをチェックする場合は、呼び出し元の__class__
呼び出しの一部としてそれに対して?
class A:
def Apple(self):
print "Hello"
b=B()
b.Bad(self.__class__)
class B:
def Bad(self, cls):
print "dude"
print "Calling class:", cls
a=A()
a.Apple()
結果:
Hello
dude
Calling class: __main__.A
これが不適切な形式であり、inspect
を使用することが呼び出し元のクラスを取得するための好ましい方法である場合は、その理由を説明してください。私はまだより深いPython概念について学習しています。
Inspect.stack()の戻り値にインデックスを付ける代わりに、メソッドinspect.currentframe()を使用して、インデックス付けを回避できます。
prev_frame = inspect.currentframe().f_back
the_class = prev_frame.f_locals["self"].__class__
the_method = prev_frame.f_code.co_name
スタックからクラス変数にクラスインスタンス名を格納するには:
import inspect
class myClass():
caller = ""
def __init__(self):
s = str(inspect.stack()[1][4]).split()[0][2:]
self.caller = s
def getInstanceName(self):
return self.caller
この
myClassInstance1 = myClass()
print(myClassInstance1.getInstanceName())
印刷されます:
myClassInstance1