Python 内省调用对象

Python 内省调用对象,python,introspection,Python,Introspection,我如何从b.func()中内省A的实例(即A的实例的self): 将其作为参数传递给b.func()。通过重构代码使其像 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 或 通常,我们不希望func能够访问A的调用

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


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

通过重构代码使其像

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


通常,我们不希望
func
能够访问
A
的调用实例,因为这会中断。在
b.func
内部,您应该可以访问传递的任何arg和kwargs、实例
b
(通过
self
此处)的状态/属性以及任何挂起的全局变量

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

  • 将调用对象作为参数传递给函数
  • 在使用
    func
    之前,请在
    b
    实例上显式添加调用方句柄,然后通过
    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()
    
    输出:

    <__main__.A instance at 0x15bd9e0>
    
    
    

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

    我同意本杰明的观点-把它作为论点传给b.func(),不要反省


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

    这是我的变通方法,但我想知道如何避免这种情况,这不是变通方法。这就是你给其他函数上下文的方式。我已经按照你的方式实现了它并继续进行,但我很好奇知道。。。此外,我认为在我的具体设计中,它可能更优雅。你的具体设计是什么?不过,我很怀疑。“显性比隐性好”同意。从技术上讲,您可以获取调用者,但是
    b.func()
    真的没有必要知道谁调用了它注意,在Python 2.x中,最好从
    object
    继承,而不是什么都不继承,这样您就可以使用新样式的类。没有可移植的方法可以做到这一点(在CPython中执行此操作的唯一方法是抓取父帧并检查它,但并非所有Python实现都公开此数据)实际上有很多
    A
    s可以调用
    B
    的实例。我不想把它们都放在
    B
    中instance@Johnathan,在示例代码段中,B是由A生成的,但不清楚它们是否由许多不同的As保存和使用。听起来您可能希望在调用B.func时准确地传递正确的A,如在我的第二个例子中。这是脆弱的(我们可以构造很多不起作用的情况)和不可移植的(
    inspect.currentframe
    是一个实现细节)。+1回答问题(不管这样做是否明智)。这在哪里不起作用?我怀疑“免责声明”about
    currentframe()
    暗指Stackless(不是Jython或Iron Python)…有人能证实这一点吗?@Mike你没有抓住重点,我不是说你重写了你的代码而不是
    pdb
    。假设你在ipython,你在
    B.func
    中得到了一个未经处理的异常。然后你可以使用神奇的
    %debug
    ,你就在
    func
    的主体中了。从那里你就拥有了整个系统的全部功能你可以输入
    import-inspect
    ,做任何内省可能对你有帮助的事情。仅仅因为一个工具可能被滥用,并不意味着它永远不应该被滥用used@wim事实上,这取决于社区是否有助于不仅仅是海报。这就是为什么它得到了反对票。这是一个信号,表明什么是ou posted对于OP来说是一个糟糕的解决方案。我发现这一切都令人惊讶。人们是否认为Python的内省能力应该保密,仅仅因为它通常不是正确的事情?只有一个答案给出了正确的事实,而人们对它投了反对票?事实就是事实。反对者是否反对透露这一点“秘密知识”?你们都不知道OP为什么要寻找这个,因此你们不能判断它是错的。当然,在某些情况下,这种类型的自省是有价值的。所以,imho,可以警告它,但不应该否决ans,因为它揭示了如何做到这一点。
    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>