检查是否从 class 内部调用了方法

Checking whether a method was called from inside the class

This 最近的问题引起了我的兴趣,我们是否可以在 python 中模拟私有变量行为。我试图在检查模块的帮助下做到这一点。

我的计划是检查 __getattribute__ 方法是否被调用 class 的内部,类似于 的答案。

根据我的理解,我可以使用 f_back 获取下一个外部框架对象,直到我最终从调用它的地方到达 class。令我惊讶的是,所有 frame.__self__ 的调用都导致了 AttributeError ,直到我最终通过过度调用 f_back:

到达 None
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 从 class 内部调用 __getattribute__(我会假设逐帧返回我应该到达它被调用的 class)我能想到这不起作用的两种可能性。

  1. 答案发布后有什么变化吗?
  2. 我遗漏了一个关键细节

由于我的代码与上面提到的答案中发布的代码非常相似,我会假设它与 python.

的版本有关

所以我的问题是,我如何检查从什么 class 调用的方法?还有其他方法吗?但最重要的是,为什么 这个 代码不起作用?

尽管任务被认为是不可能完成的,但似乎只需将 __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__ 属性并且没有 return 该框架的 class - 我假设它根据上述答案。