-6ren">
gpt4 book ai didi

python-3.x - 如何创建元组的循环引用?

转载 作者:行者123 更新时间:2023-12-04 11:01:13 24 4
gpt4 key购买 nike

由于历史原因(阅读:可怕的 type(t) == tuple 检查),我发现自己需要将圆形图卡住为 tuple 的集合。对象。显然,这并不理想:

>>> head = ("head", None)
>>> a = ("a", ("b", ("c", head)))
>>> head[1] = a
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
head[1] = a
TypeError: 'tuple' object does not support item assignment

然而,我并不是真正相信 TypeError s,并怀疑,通过特定于实现的hackery,这是可以做到的。
  • 我怎样才能在不冒越界或导致其他 C 未定义行为的风险的情况下产生这种怪物?
  • Garbage Collector 的循环依赖释放部分能否应对这种情况?
  • 最佳答案

    I, however, am not really a great believer in TypeErrors, and suspect that, through implementation-specific hackery, this can be done.



    可悲的是,你是对的:

    from ctypes import Structure, c_ssize_t, c_void_p, py_object, pythonapi

    pythonapi.Py_DecRef.argtypes = py_object,


    def mutable(tup):
    # We are generating this class dynamically because the size of ob_item
    # varies according to the size of the given tuple
    class PyTupleObject(Structure):
    _fields_ = [('ob_refcnt', c_ssize_t),
    ('ob_type', c_void_p),
    ('ob_size', c_ssize_t),
    ('ob_item', py_object * len(tup))]

    @classmethod
    def from_tuple(cls, tup):
    instance = cls.from_address(id(tup))
    # Save a reference to tup on the instance, as we are using it directly from memory
    # and don't want it to be garbage collected
    instance.original = tup
    return instance

    def __setitem__(self, idx, val):
    # Replacing a value in self.ob_item doesn't decref the old value but does indref the new value
    pythonapi.Py_DecRef(self.ob_item[idx])
    self.ob_item[idx] = val

    def __getitem__(self, idx):
    return self.ob_item[idx]

    def __iter__(self):
    return iter(self.ob_item)

    def __len__(self):
    return len(self.ob_item)

    def __contains__(self, val):
    return val in self.ob_item

    return PyTupleObject.from_tuple(tup)


    if __name__ == '__main__':
    tup = (None,)
    mut_tup = mutable(tup)
    mut_tup[0] = tup
    print(tup is tup[0]) # Outputs "True"

    How can I produce this monstrosity without risking going Out of Bounds or causing other C Undefined Behaviour?



    我们通过定义成员 ob_item 来防止越界访问成为 py_object * len(tup) .

    Can the circular dependency freeing part of the Garbage Collector cope with such a thing?



    不!元组应该是不可变的,因此不期望对自身有循环引用。这就是为什么他们不实现 tp_clear方法,python 垃圾收集器使用该方法来中断引用循环并收集涉及的垃圾。更多详情 here

    关于python-3.x - 如何创建元组的循环引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58783138/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com