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

问题描述 投票:-1回答:1

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__(我会假设逐帧回到我应该到达它所称的类)我可以想到两个可能性为什么这个不工作。

  1. 自答案发布以来,情况有所改变?
  2. 我错过了一个关键的细节

由于我的代码与上面提到的答案中发布的代码非常相似,所以我会假设它与python的版本有关。

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

python python-3.x python-3.7 inspect
1个回答
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__属性并且不返回该框架的类 - 我认为它是从上述答案中做到的。

© www.soinside.com 2019 - 2024. All rights reserved.