你可以取消引用从Python中id
函数检索的变量id吗?例如:
dereference(id(a)) == a
我想从学术角度来了解;我知道有更实用的方法。
答案 0 :(得分:24)
这是一个实用函数,基于由“Tiran”在讨论Hophat Abc comment中制作的referenced,它将在Python 2和3中都有效:
import _ctypes
def di(obj_id):
""" Inverse of id() function. """
return _ctypes.PyObj_FromPtr(obj_id)
if __name__ == '__main__':
a = 42
b = 'answer'
print(di(id(a))) # -> 42
print(di(id(b))) # -> answer
答案 1 :(得分:3)
不容易。
您可以通过gc.get_objects()
列表递归,测试每个对象是否具有相同的id()
,但这不是很实用。
id()
函数无意可解除引用;它基于内存地址的事实是一个CPython实现细节,其他Python实现不遵循。
答案 2 :(得分:2)
有几种方法,并不难做到:
在O(n)
In [1]: def deref(id_):
....: f = {id(x):x for x in gc.get_objects()}
....: return f[id_]
In [2]: foo = [1,2,3]
In [3]: bar = id(foo)
In [4]: deref(bar)
Out[4]: [1, 2, 3]
评论中的平均速度更快(感谢@Martijn Pieters):
def deref_fast(id_):
return next(ob for ob in gc.get_objects() if id(ob) == id_)
最快的解决方案是@martineau的答案,但确实需要暴露python内部。上面的解决方案使用标准的python构造。
答案 3 :(得分:2)
di模块有一个C函数,如果对象没有被垃圾回收,你可以这样做:http://www.friday.com/bbum/2007/08/24/python-di/
答案 4 :(得分:1)
这是另一个答案改编自另一个comment,这个由“彼得·费恩”改编,在讨论中,Hophat Abc在他自己对自己的问题的回答中提到了这个问题。
虽然不是一般性答案,但在您了解要查找其ID的对象类的情况下可能仍然有用 - 而不是它们是任何的ID 。基本思想是创建一个跟踪自身实例和子类的类。我觉得即使有这个限制,这也许是一项有价值的技术。
import weakref
class InstanceTracker(object):
""" base class that tracks instances of its subclasses using weakreferences """
class __metaclass__(type):
""" Metaclass for InstanceTracker """
def __new__(cls, name, bases, dic):
cls = super(cls, cls).__new__(cls, name, bases, dic)
cls.__instances__ = weakref.WeakValueDictionary()
return cls
def __init__(self, *args, **kwargs):
self.__instances__[id(self)]=self
super(InstanceTracker, self).__init__(*args, **kwargs)
@classmethod
def find_instance(cls, obj_id):
return cls.__instances__.get(obj_id, None)
if __name__ == '__main__':
class MyClass(InstanceTracker):
def __init__(self, name):
super(MyClass, self).__init__()
self.name = name
def __repr__(self):
return '{}({!r})'.format(self.__class__.__name__, self.name)
obj1 = MyClass('Bob')
obj2 = MyClass('Sue')
print MyClass.find_instance(id(obj1))
print MyClass.find_instance(id(obj2))
print MyClass.find_instance(42)
输出:
MyClass('Bob')
MyClass('Sue')
None