社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

系统。refcount()返回的值比预期的python3大得多

Rohit Agharkar • 3 年前 • 1110 次点击  

我正在用python学习GIL,并尝试运行sys。refcount()和接收的值为148。这可能是一个非常简单的问题,任何帮助都将不胜感激。

为什么值是148而不是2?

import sys

c = 1
print(sys.getrefcount(c))

>>> 148
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129862
 
1110 次点击  
文章 [ 2 ]  |  最新文章 3 年前
Alexander
Reply   •   1 楼
Alexander    3 年前

int 这很特别。

它的值非常多(双关语)而且很小,这是远对象开销方面最糟糕的情况(它浪费时间进行分配,GCs变得更慢,因为它们有更多堆对象要扫描,并且浪费时间进行引用计数和取消分配)。通常情况下,语言运行时会花费大量时间来优化特殊情况,比如 智力 , bool

根据Python的具体实现,有可能 智力 对象表示为:

  1. 常规的、普通的堆分配对象(即,没有特殊的优化)。
  2. 作为常规的堆分配对象,但使用一个共享对象池来表示所有最常见的值。(例如,每一次 1 是同一个对象,被引用 到处都是 1. (已使用)
  3. 或者作为一个 tagged pointer ,这完全不涉及堆分配(对于适当小的整数值)。

在案例2或3中,如果它是“普通”对象,它的引用计数将不是您可能期望的。

Tim Peters
Reply   •   2 楼
Tim Peters    3 年前

你的Python代码不是唯一运行的东西。Python标准库的大部分内容都是编写的 在里面 Python,这取决于您使用的shell,这可能会导致在第一次键入之前导入相当多的模块。在CPython 3.10.0的空闲状态下:

>>> import sys
>>> len(sys.modules)
159

因此,只要到达提示(!)模块“在封面下”。

“小”整数对象由CPython实现跨用途共享。所有这些模块中的每个3实例都会增加3的refcount。以下是其他一些:

>>> for i in range(-10, 11):
...     print(i, sys.getrefcount(i))
-10 3
-9 3
-8 3
-7 3
-6 3
-5 9
-4 5
-3 12
-2 25
-1 190
0 914
1 804
2 363
3 144
4 202
5 83
6 83
7 38
8 128
9 54
10 64

所以3“相当受欢迎”,但0是容易的赢家。但是没有其他东西在使用,例如-10或-9。

但请注意 知道 这对你来说没有实际价值。Python是否以及何时共享不可变对象由实现定义,并且可以(而且确实如此!)在不同版本之间进行更改。