dill.detect.at无法引用' 0x1023d2600'

时间:2014-09-13 01:43:36

标签: python garbage-collection dill

更多挖到莳萝。特别是detect.at方法,它是一个调用:

def _locate_object(address, module=None):
    """get object located at the given memory address (inverse of id(obj))"""
    special = [None, True, False] #XXX: more...?
    for obj in special:
        if address == id(obj): return obj
    if module:
        if PY3:
            objects = iter(module.__dict__.values())
        else:
            objects = module.__dict__.itervalues()
    else: objects = iter(gc.get_objects())
    for obj in objects:
        if address == id(obj): return obj
    # all bad below... nothing found so throw ReferenceError or TypeError
    from weakref import ReferenceError
    try: address = hex(address)
    except TypeError:
        raise TypeError("'%s' is not a valid memory address" % str(address))
    raise ReferenceError("Cannot reference object at '%s'" % address)

为什么我无法"得到"看似位于地址的字符串对象:4332529152

>>> class Parent():
...     name="Big Papa"
...     def get_hitched(partner):
...             return name + "+" + partner + "TLFE"
... 
>>> johnny = Parent()
    >>> johnny = Parent()
>>> johnny.get_hitched("Mary")
'Big Papa + Mary TLFE'
>>> billy = johnny.get_hitched
>>> billy("Junebug")
'Big Papa + Junebug TLFE'
>>> dill.detect.reference(billy)
4299844816
>>> dill.detect.reference(johnny.get_hitched)
4299844816
>>> dill.detect.reference(johnny)
4299844816
>>> dill.detect.reference(johnny.name)
4332529152
>>> dill.detect.reference(Parent)
4332953328
>>> dill.detect.at(4332529152)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mikekilmer/Envs/GLITCH/lib/python2.7/site-packages/dill/dill.py", line 738, in _locate_object
    raise ReferenceError("Cannot reference object at '%s'" % address)
ReferenceError: Cannot reference object at '0x1023d2600'
>>> 0x1023d2600
4332529152
>>> id(johnny.name)
4332529152
>>> type(johnny.name)
<type 'str'>

2 个答案:

答案 0 :(得分:1)

Detect.at()接受一个引用号,如果它是一个将由垃圾收集模块处理的引用号,则返回与之关联的对象。否则返回ReferenceError:和参考号的十六进制值。

例如,实例属性不由GC管理,因为它们在链接到的对象被销毁时将被销毁。

正如罗比在评论中所说:

他们在这里所做的就是搜索gc.get_objects()并按id比较对象 - 这正是你应该如何使用id。您无法取消引用johnny.name的实际原因是垃圾收集器不直接跟踪类/实例属性 - 没有必要,因为您可以在销毁对象时销毁它们#&# 39;重新联系到。

十六进制数只是在输入hex()的参考号上调用dill.detect.at()方法的结果。

答案 1 :(得分:0)

这里的基本问题:对象的id()不是它的地址。它可能恰好在CPython中,但它不是你可以利用的东西。我不知道_locate_object应该用于什么,但这看起来像是根本不好的代码。你能解释一下你真正想要在这里完成什么吗?

Python不适用于内存地址,它适用于对象引用。每个对象都有一个标识,这是一个整数。有些Pythons只在请求id()时分配顺序整数,仅此而已。你可以确定的是,没有两个同时存在的不同对象具有相同的id,并且对象的id在其整个生命周期中永远不会改变。