This最近的问题引起了我的兴趣,我们是否可以模拟python中的私有变量行为。我试图在检查模块的帮助下做到这一点。
我的计划是检查是否从类内部调用__getattribute__
方法,类似于this的回答。
根据我的理解,我可以使用f_back
获取下一个外框对象,直到我最终从它被调用的类开始。令我惊讶的是,frame.__self__
的所有调用导致了AttributeError,直到我最终通过过度调用None
到达f_back
:
import inspect
class MyClass:
def __init__(self):
self.variable = 1
def __getattribute__(self, attr):
frame = inspect.currentframe()
try:
while frame != None:
try:
frame.__self__ # Can I do that?
print("Yes I can")
except AttributeError:
print("Nope")
frame = frame.f_back
finally:
del frame
return super().__getattribute__(attr)
def get_variable(self):
return self.variable
A = MyClass()
print(A.get_variable())
因为所有我得到的都是“Nope”,即使getter从类中调用__getattribute__
(我会假设逐帧回到我应该到达它所称的类)我可以想到两个可能性为什么这个不工作。
由于我的代码与上面提到的答案中发布的代码非常相似,所以我会假设它与python的版本有关。
所以我的问题是,如何检查被调用方法的类是什么?还有其他方法吗?但最重要的是,为什么这段代码不起作用?
尽管任务被认为是不可能的,但似乎只需用__self__
替换f_locals['self']
就可以轻松实现我想要的行为。
import inspect
class MyClass:
def __init__(self):
self.variable = 1
def __getattribute__(self, attr):
frame = inspect.currentframe()
try:
locals = frame.f_back.f_locals
if locals.get('self', None) is self:
print("Called from this class!")
else:
print("Called from outside of class!")
finally:
del frame
return super().__getattribute__(attr)
def get_variable(self):
return self.variable
A = MyClass()
print(A.get_variable())
当前代码不应该起作用,因为框架对象本身没有__self__
属性并且不返回该框架的类 - 我认为它是从上述答案中做到的。