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

时间:2019-02-26 01:31:17

标签: python python-3.x python-3.7 inspect

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())

由于我所得到的只是“不”,即使吸气剂是从班级内部调用的__getattribute__(我会假设逐帧返回,所以我应该到达被其称为的班级)可以想到两种方法导致此方法不起作用。

  1. 发布答案后发生了什么变化?
  2. 我缺少关键细节

由于我的代码与上述答案中的代码超级相似,因此我将假定它与python版本有关。

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

1 个答案:

答案 0 :(得分:0)

尽管任务被认为是不可能的,但似乎我想要的行为可以通过简单地将__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__属性,并且不返回该帧的类,因此当前代码不应起作用-我认为是从上述答案中得出的。