0

0

如何让一个类支持 len(obj) 但实际长度由外部计算

舞夢輝影

舞夢輝影

发布时间:2026-01-27 19:33:09

|

639人浏览过

|

来源于php中文网

原创

__len__ 必须返回非负整数且不能懒计算,因其被 len() 强制调用并要求即时返回 int;可行方案是用实例属性缓存长度,由外部显式更新,__len__ 仅透传该值。

如何让一个类支持 len(obj) 但实际长度由外部计算

为什么 __len__ 必须返回 int 且不能懒计算

len() 的底层调用强制要求 __len__ 返回非负整数,且不能是 None 或延迟对象(比如 functools.cached_property 包裹的函数)。一旦返回值不是 int,就会抛出 TypeError: object of type 'X' has no len()。更关键的是,__len__ 在每次 len(obj) 调用时都会执行——它天然不缓存,也不支持“外部计算后注入”的语义。

用属性代理 + 外部更新模拟“外部计算长度”

真正可行的做法是:把长度值存在实例属性里,由外部逻辑负责设置;__len__ 只做透传。这规避了协议限制,也符合“实际长度由外部计算”的需求。

  • __len__ 内直接返回一个实例变量(如 self._cached_len),不参与计算
  • 外部代码在需要时调用类似 obj._update_length() 或直接赋值 obj._cached_len = compute_real_length(obj)
  • 如果想防止误用,可加一层检查:if not hasattr(self, '_cached_len'): raise RuntimeError("length not initialized")
  • 注意:该方案不自动同步,外部必须显式更新,否则 len(obj) 返回过期值

避免踩坑:不要在 __len__ 里调用外部函数

常见错误是试图在 __len__ 中触发网络请求、查数据库或遍历大文件——这会让所有依赖 len() 的代码(比如 if obj:for 循环判断、list(obj))变得不可预测且极慢。

  • Python 很多内置行为隐式调用 len(),例如 bool(obj) 在未定义 __bool__ 时会 fallback 到 len(obj) != 0
  • 第三方库(如 Pydantic、NumPy、Django ORM)也可能在序列化或验证时读取 len()
  • 若外部计算成本高,应在业务逻辑层主动缓存结果,再写入 _cached_len,而不是塞进 __len__

示例:带手动刷新的可长度化容器

class LazyLenList:
    def __init__(self, items):
        self.items = items
        self._cached_len = None  # 初始未计算
def __len__(self):
    if self._cached_len is None:
        raise ValueError("length not computed yet. Call update_length() first.")
    return self._cached_len

def update_length(self):
    # 外部计算逻辑放这里,比如过滤、IO、聚合等
    self._cached_len = len([x for x in self.items if x > 0])  # 示例:只算正数

Meku
Meku

AI应用和网页开发工具

下载

使用时必须先调用 obj.update_length(),再用 len(obj) —— 这个控制权交给了使用者,也明确了“长度非实时”的契约。

真正难的不是实现,而是让所有协作者意识到:这个 len() 不是自洽的,它依赖外部状态同步。漏掉一次 update_length(),后续所有基于长度的判断都可能错。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

775

2023.08.22

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

422

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

73

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

924

2023.09.19

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

924

2023.09.19

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

356

2023.06.29

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号