Python反射:如何从内部获取方法的特定实例的id



我不能只使用像id(self.methodname)这样简单的东西,因为场景比它复杂一点,因为我在做一些时髦的动态东西。我会尽量把整个情况解释清楚。

class A:
def __init__(self):
self.ax = 10
def amethod(self, other):
print(self.ax)
print(other.bx)
class B:
def __init__(self):
self.fun_dict = {}
self.bx = 20
def run_in_dict(self):
for fn in self.fun_dict.values():
fn()

首先我们有两节课。其中一个有一个字典,其中包含作为值的函数和作为键的函数id。在实际程序中,这是用于存储回调函数的,而fun_dict的名称与on_receiving类似。

a = A()
b = B()
import types
bound_to_b = types.MethodType(a.amethod, b)
print(bound_to_b)  # <bound method A.amethod of <__main__.B object at 0x7fdcdacf1850>>
print(bound_to_b())  # prints 10 and 20
b.fun_dict[id(bound_to_b)] = bound_to_b
b.run_in_dict() # also prints 10 and 20
a.ax = 2
b.run_in_dict() # prints 2 and 20, as expected

到目前为止还不错。所有这些都按预期工作:我们现在有一个方法bound_to_b,它同时绑定到两个对象,并存储在b的fun_dict中。是的,我知道这是一种可怕的代码,但这是一个学习项目,所以别担心,没有人会接触到它

但现在假设我稍后要从b中删除绑定方法。也就是说,从b.fun_dict中删除它的引用。如果我在外面做,并将id保存在其他地方,这很容易,但我的问题是:有没有一种方法可以在不存储id的情况下从amethod内部做?或者,如果不可能,除了id之外,还有什么东西可以用作dict密钥吗?

事实上,print(id(self.amethod))每次都打印不同的内存位置,所以它没有帮助。dir(bound_to_b)内部也没有其他东西向我扑来。

似乎你无法以我想要的方式在方法中获得对方法的引用,至少在不使用inspect等更棘手的东西的情况下也是如此。无论如何,尝试在函数中存储数据可能是一个非常愚蠢的想法,我想这就是为什么这么难做到的原因。相反,我为回调函数制作了一个精简包装器类。这是我想要的,尽管它确实需要向方法传递一个额外的参数:

import types
class Callback:
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
kwargs["cbid"] = id(self)
self.f(*args, **kwargs)

class A:
def __init__(self):
self.ax = 10
def amethod(self, other, cbid=None):
print("from inside amethod")
other.fun_dict.pop(cbid)
class B:
def __init__(self):
self.fun_dict = {}
self.bx = 20
def run_in_dict(self):
for fn in list(self.fun_dict.values()):
print("before:", self.fun_dict)
fn()
print("after:", self.fun_dict)
a = A()
b = B()
bound = Callback(types.MethodType(a.amethod, b))
b.fun_dict[id(bound)] = bound
b.run_in_dict()

最新更新