[英]How to get the class from which a method was called?
get_calling_class
function 必須通過返回調用Af
方法的方法的 class 來通過以下測試:
class A:
def f(self): return get_calling_class()
class B(A):
def g(self): return self.f()
class C(B):
def h(self): return self.f()
c = C()
assert c.g() == B
assert c.h() == C
走堆棧應該給出答案。
理想情況下,答案應該在調用者的堆棧幀中。
問題是,堆棧幀只記錄了 function
名稱(如:'f'、'g'、'h' 等)有關的任何信息
課程丟失。 試圖對丟失的信息進行逆向工程,
通過導航 class 層次結構(與
堆棧框架),並沒有讓我走得太遠,而且變得復雜。
因此,這是一種不同的方法:
將 class 信息注入堆棧幀
(例如使用局部變量),
並從稱為 function 中讀取。
import inspect
class A:
def f(self):
frame = inspect.currentframe()
callerFrame = frame.f_back
callerLocals = callerFrame.f_locals
return callerLocals['cls']
class B(A):
def g(self):
cls = B
return self.f()
def f(self):
cls = B
return super().f()
class C(B):
def h(self):
cls = C
return super(B, self).f()
def f(self):
cls = C
return super().f()
c = C()
assert c.h() == C
assert c.g() == B
assert c.f() == B
有關的:
從檢查堆棧獲取完全合格的方法名稱
不修改子類的定義:
添加了一個“外部”裝飾器,用於包裝 class 方法。
(至少作為臨時解決方案。)
import inspect
class Injector:
def __init__(self, nameStr, valueStr):
self.nameStr = nameStr
self.valueStr = valueStr
# Should inject directly in f's local scope / stack frame.
# As is, it just adds another stack frame on top of f.
def injectInLocals(self, f):
def decorate(*args, **kwargs):
exec(f'{self.nameStr} = {self.valueStr}')
return f(*args, **kwargs)
return decorate
class A:
def f(self):
frame = inspect.currentframe()
callerDecoratorFrame = frame.f_back.f_back # Note:twice
callerDecoratorLocals = callerDecoratorFrame.f_locals
return callerDecoratorLocals['cls']
class B(A):
def g(self): return self.f()
def f(self): return super().f()
class C(B):
def h(self): return super(B, self).f()
def f(self): return super().f()
bInjector = Injector('cls', B.__name__)
B.g = bInjector.injectInLocals(B.g)
B.f = bInjector.injectInLocals(B.f)
cInjector = Injector('cls', C.__name__)
C.h = cInjector.injectInLocals(C.h)
C.f = cInjector.injectInLocals(C.f)
c = C()
assert c.h() == C
assert c.g() == B
assert c.f() == B
我發現這個鏈接很有趣
(但這里沒有利用元類):
python 中的元類是什么
也許有人甚至可以替換 function 定義*,
其代碼與原始代碼重復的函數;
但添加了當地人/信息,直接在他們的 scope 中。
*
也許在 class 定義完成之后;
可能在 class 創建期間(使用元類)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.