内省调用对象 [英] Introspect calling object

查看:69
本文介绍了内省调用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从b.func()内部检查A的实例(即A实例的 self ):

How do I introspect A's instance from within b.func() (i.e. A's instance's self):

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

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

推荐答案

通常,我们不希望func有权访问A的调用实例,因为这会破坏

In general we don't want that func to have access back to the calling instance of A because this breaks encapsulation. Inside of b.func you should have access to any args and kwargs passed, the state/attributes of the instance b (via self here), and any globals hanging around.

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

If you want to know about a calling object, the valid ways are:

  1. 将调用对象作为参数传递给函数
  2. 在使用func之前的某个时间,将调用者的句柄明确添加到b实例上,然后通过self访问该句柄.
  1. Pass the calling object in as an argument to the function
  2. Explicitly add a handle to the caller onto b instance sometime before using func, and then access that handle through self.

但是,尽管有了该免责声明,但仍然值得知道,python的自省功能在某些情况下足以访问调用者模块.在CPython实现中,这是在不更改接口的情况下访问调用A实例的方法:

However, with that disclaimer out of the way, it's still worth knowing that python's introspection capabilities are powerful enough to access the caller module in some cases. In the CPython implementation, here is how you could access the calling A instance without changing your interfaces:

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的情况下,访问这样的堆栈帧并不是明智的设计决定.

This might be a useful trick to know about for debugging code sometimes. But it would not be a sensible design decision to ever access the stack frames like this in the case that B.func actually needed to use A for any reason.

这篇关于内省调用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆