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回答问题(不管这样做是否明智)。这在哪里不起作用?我怀疑“免责声明”aboutcurrentframe()
暗指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>