Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的weakref到底是什么?_Python_Python 3.x_Python Internals - Fatal编程技术网

Python中的weakref到底是什么?

Python中的weakref到底是什么?,python,python-3.x,python-internals,Python,Python 3.x,Python Internals,令人惊讶的是,\uuuuuweakref\uuuuu没有明确的文档。解释了弱引用\uuuuu weakref\uuuuuu的文档中也很快提到了代码>\uuuuuu weakref\uuuuu。但是我找不到任何关于本身的东西 “代码”到底是什么? -它是否只是一个充当标志的成员:如果存在,对象可能被弱引用? -或者它是一个可以被重写/赋值以获得所需行为的函数/变量?如何?变量\uuuu weakref\uuuu是一个属性,它使对象支持弱引用并保留对对象的弱引用 python文档对其进行了如下解释:

令人惊讶的是,
\uuuuuweakref\uuuuu
没有明确的文档。解释了弱引用<代码>\uuuuu weakref\uuuuuu的文档中也很快提到了代码>\uuuuuu weakref\uuuuu。但是我找不到任何关于
本身的东西

“代码”到底是什么? -它是否只是一个充当标志的成员:如果存在,对象可能被弱引用?
-或者它是一个可以被重写/赋值以获得所需行为的函数/变量?如何?

变量
\uuuu weakref\uuuu
是一个属性,它使对象支持弱引用并保留对对象的弱引用

python文档对其进行了如下解释:

当对引用对象的唯一剩余引用是弱引用时,垃圾收集可以随意销毁引用对象并将其内存用于其他用途

因此,弱引用的职责是为对象提供条件,以便能够进行垃圾收集,而不管对象的类型和范围如何

关于
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,我们可以先查看文档,文档对其进行了

默认情况下,类的实例具有用于属性存储的字典。这会为实例变量很少的对象浪费空间。创建大量实例时,空间消耗可能会变得非常严重

可以通过在类定义中定义
\uuuuuu插槽
来覆盖默认值。
\uuuuuuuuuuuuuuuuuuuuuuuu
声明获取一系列实例变量,并在每个实例中保留足够的空间来保存每个变量的值。节省空间是因为没有为每个实例创建
\uuu dict\uu

现在,由于通过使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。其中
\uuuu weakref\uuuu
是每个对象的必要变量,以便能够处理弱引用

此外,除了所有这些之外,
对象的文档说明如下:

可以为该类变量分配一个字符串、iterable或一系列字符串,这些字符串具有实例使用的变量名<代码>\\\\\\\\\/code>为声明的变量保留空间,并防止为每个实例自动创建
\\\\\\\\\\\\\\/code>和
\\\\\\\\\\/code>

因此,简而言之,我们可以得出结论,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>用于手动管理存储分配,因为
\uuuuuuuuuuuu,因此,
\uuuuuuuuuuuuuuuuuuuuuuuuu
将控制
\uuuuuuuwakref\uuuuuuuuuuu
属性

此外,文档还向您展示了使用
\uuuuuuu插槽\uuuuuu
创建对象以支持弱引用的方法:

>>> import weakref
>>> class A: pass
...
>>> a = A()
>>> b = weakref.ref(a)
>>> c = weakref.ref(a)
>>> c is b, b is a.__weakref__
True, True
>>> weakref.getweakrefs(a)
[<weakref at 0x10dbe5270; to 'A' at 0x10dbc2fd0>]
如果每个实例都没有
\uuuuukref\uuuuu
变量,则定义
\uuuuuuu插槽的类不支持对其实例的弱引用。如果需要弱引用支持,则将
''weakref'
添加到
\uuuuu slots
声明中的字符串序列中

以下是python 3.X中的一个示例:

>>> class Test:
...     __slots__ = ['a', 'b']
... 
>>> 
>>> import weakref
>>> 
>>> t = Test()
>>> 
>>> r = weakref.ref(t)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot create weak reference to 'Test' object
>>> 
>>> class Test:
...     __slots__ = ['a', 'b', '__weakref__']
... 
>>> t = Test()
>>> r = weakref.ref(t)
>>> 
>>> t.__weakref__
<weakref at 0x7f735bc55d68; to 'Test' at 0x7f735bc51fc8>
有趣的是,这篇文章在这个话题上没有什么启发性:

如果每个实例都没有
\uuuuukref\uuuuu
变量,则定义
\uuuuuuu插槽的类不支持对其实例的弱引用。如果需要弱引用支持,则将
''weakref'
添加到
\uuuuu slots
声明中的字符串序列中

以下选项更有用:

当类型的
\uuuu slots\uuuu
声明包含名为
\uuuu weakref\uuuu
的插槽时,该插槽将成为该类型实例的弱引用列表头,并且该插槽的偏移量存储在类型的
tp\u weaklistoffset

弱引用形成堆栈。该堆栈的顶部(对对象的最新弱引用)可通过
\uuuuuwakref\uuuu
获得。Weakrefs尽可能重复使用,因此堆栈通常为空或包含单个元素

例子 首次使用
weakref.ref()
时,将为目标对象创建一个新的弱引用堆栈。此堆栈的顶部是新的弱引用,并存储在目标对象的
\uuuuuuwakref\uuuuu
中:

>>> import weakref
>>> class A: pass
...
>>> a = A()
>>> b = weakref.ref(a)
>>> c = weakref.ref(a)
>>> c is b, b is a.__weakref__
True, True
>>> weakref.getweakrefs(a)
[<weakref at 0x10dbe5270; to 'A' at 0x10dbc2fd0>]

现在
c
是堆栈中一个新的弱引用。

\uuuuwakref\uuuwk
只是一个不透明对象,将所有弱引用引用引用到当前对象。实际上,它是(或者有时是
weakproxy
)的一个实例,它既是对对象的弱引用,也是对该对象所有弱引用的双链接列表的一部分

这只是一个实现细节,允许垃圾收集器通知弱引用其引用对象已被收集,并且不再允许访问其底层指针

弱引用不能依赖于检查它引用的对象的引用计数。这是因为内存可能已被回收,现在正被另一个对象使用。最好的情况是VM崩溃,最坏的情况是弱引用将允许访问它最初没有引用的对象。这就是为什么垃圾收集器必须通知弱引用其引用对象不再有效


有关此对象的结构和C-API,请参见。而实现细节是

我在引号文档中没有看到任何关于
\uuuuuuweakref\uuuuuuuu
实际功能的内容(它包含弱引用单例)。想补充一下吗?@dhke:这里也一样。。。弱引用的概念很清楚,我真的很想知道
的确切含义和功能
>>> import weakref
>>> class A: pass
...
>>> def callback(ref): pass
...
>>> a = A()
>>> b = weakref.ref(a)
>>> c = weakref.ref(a, callback)
>>> c is b, b is a.__weakref__
False, True
>>> weakref.getweakrefs(a)
[<weakref at 0x10dbcfcc0; to 'A' at 0x10dbc2fd0>,
 <weakref at 0x10dbe5270; to 'A' at 0x10dbc2fd0>]