内省调用对象

时间:2011-09-01 15:06:54

标签: python introspection

如何在A内(即b.func()的实例的 A )内省self的实例:

class A():
    def go(self):
        b=B()
        b.func()

class B():
    def func(self):
        # Introspect to find the calling A instance here

4 个答案:

答案 0 :(得分:25)

一般情况下,我们不希望func有权访问A的调用实例,因为这会导致encapsulation中断。在b.func内部,您应该可以访问任何传递的args和kwargs,实例b的状态/属性(通过此处self)以及任何悬空的全局变量。

如果您想了解调用对象,有效的方法是:

  1. 将调用对象作为参数传递给函数
  2. 在使用b之前的某个时间,在func实例上向调用者显式添加句柄,然后通过self访问该句柄。
  3. 然而,放弃了免责声明,仍然值得知道python的内省功能在某些情况下足以访问调用程序模块。在CPython实现中,以下是在不更改接口的情况下访问调用A实例的方法:

    class A():
        def go(self):
            b=B()
            b.func()
    
    class B():
        def func(self):
            import inspect
            print inspect.currentframe().f_back.f_locals['self']
    
    if __name__ == '__main__':
        a = A()
        a.go()
    

    输出:

    <__main__.A instance at 0x15bd9e0>
    

    这有时可能是了解调试代码的有用技巧。但是,B.func出于任何原因A实际需要使用{{1}}这样的情况下,访问这样的堆栈帧并不是一个明智的设计决策。

答案 1 :(得分:5)

您将其作为参数传递给b.func()

答案 2 :(得分:0)

通过将代码重构为

来完成此操作
class A():
    def go(self):
        b = B(self)
        b.func()

class B():
    def __init__(self, a):
        self.a = a

    def func(self):
        # Use self.a

class A():
    def go(self):
        b = B()
        b.func(self)

class B():
    def func(self, a):
        # a

答案 3 :(得分:0)

我同意本杰明 - 将其作为参数传递给b.func()并且不反省!!!!

如果你的生活真的依赖于它,那么我认为你可以从this answer中推断出答案。