内省调用对象

Jon*_*han 16 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
Run Code Online (Sandbox Code Playgroud)

wim*_*wim 30

一般来说,我们不希望它func有权访问调用实例,A因为这会破坏封装.在b.func你内部你应该可以访问任何传递的args和kwargs,实例的状态/属性b(通过self这里),以及任何挂起的全局变量.

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

  1. 将调用对象作为参数传递给函数
  2. b在使用之前的某个时间向调度程序显式添加一个句柄func,然后通过该句柄访问该句柄self.

但是,有了免责声明,仍然值得知道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()
Run Code Online (Sandbox Code Playgroud)

输出:

<__main__.A instance at 0x15bd9e0>
Run Code Online (Sandbox Code Playgroud)

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

  • 我发现这一切都令人惊讶.人们是否认为Python的内省能力应该保密,因为它通常不是正确的做法?只有一个答案给出了正确的事实,而人们对它进行了贬低?事实是事实.那些贬低者是否反对揭露这种"秘密知识"?你们都不知道为什么OP正在寻找这个,因此你无法判断它是错的.当然有可能出现这种类型的内省是有价值的.所以,imho,可以警告它,但不应该通过暗示来揭示它是如何完成的. (22认同)
  • +1回答问题(不管这样做是否明智).哪个不起作用?我怀疑关于`currentframe()`的"免责声明"暗指Stackless(不是Jython或Iron Python)....任何人都可以证实这一点吗? (3认同)
  • @wim实际上,这个知识不仅仅对海报有帮助,还取决于社区.这就是为什么它会下降投票.这些信号表明您发布的内容对于OP来说是一个糟糕的解决方案. (3认同)

Ben*_*son 5

你把它传递给b.func()一个参数.

  • 这不是一种解决方法.这就是你给其他函数上下文的方式. (7认同)
  • 你的具体设计是什么?不过我对它表示怀疑."明确比隐含更好" (2认同)