为什么 Python 代码使用 len() 函数而不是 length 方法?

2025-02-17 09:25:00
admin
原创
77
摘要:问题描述:我知道python有一个len()用于确定字符串大小的函数,但我想知道为什么它不是字符串对象的方法?解决方案 1:字符串确实有一个长度方法:__len__()Python 中的协议是在具有长度的对象上实现此方法并使用内置len()函数为您调用它,类似于您在可迭代的对象上实现__iter__()和使用...

问题描述:

我知道python有一个len()用于确定字符串大小的函数,但我想知道为什么它不是字符串对象的方法?


解决方案 1:

字符串确实有一个长度方法:__len__()

Python 中的协议是在具有长度的对象上实现此方法并使用内置len()函数为您调用它,类似于您在可迭代的对象上实现__iter__()和使用内置iter()函数(或在后台为您调用该方法)的方式。

有关详细信息,请参阅模拟容器类型。

这是一篇关于 Python 协议主题的好文章:Python 和最小惊讶原则

解决方案 2:

Jim 对这个问题的回答可能会有所帮助;我把它复制到这里。引用 Guido van Rossum 的话:

首先,我选择 len(x) 而不是 x.len() 是出于 HCI 的原因(def __len__() 出现得晚得多)。实际上有两个相互交织的原因,都是 HCI:

(a) 对于某些运算,前缀表示法比后缀表示法读起来更好 — 前缀(和中缀!)运算在数学中有着悠久的传统,数学家喜欢用视觉符号来帮助数学家思考问题。比较一下,我们将 x(a+b) 这样的公式重写为 xa + x*b 的简单性与使用原始 OO 表示法执行相同操作的笨拙性。

(b) 当我读到 len(x) 的代码时,我知道它正在请求某个对象的长度。这告诉我两件事:结果是一个整数,参数是某种容器。相反,当我读到 x.len() 时,我必须已经知道 x 是某种实现接口的容器,或者从具有标准 len() 的类继承而来。当未实现映射的类具有 get() 或 keys() 方法,或者非文件具有 write() 方法时,我们偶尔会感到困惑。

换个角度说,我认为“len”是一种内置操作。我不想失去它。/…/

解决方案 3:

Python 是一门实用的编程语言,而、等len()作为函数而不是方法的str原因都是实用的。list`dict`

内置len()函数直接处理内置类型:的 CPython 实现实际上返回C 结构中表示内存中任何可变大小内置对象的len()字段的值。这比调用方法要快得多——无需进行属性查找。获取集合中的项目数是一种常见操作,必须有效地处理诸如、等基本和多样化类型。ob_size`PyVarObjectstrlist`array.array

但是,为了促进一致性,当应用于len(o)用户定义类型时,Python 会调用o.__len__()作为后备。 __len__并且Python 数据模型__abs__中记录的所有其他特殊方法可以轻松创建行为类似于内置函数的对象,从而实现我们称之为“Pythonic”的富有表现力且高度一致的 API。

通过实现特殊方法,您的对象可以支持迭代、重载中缀运算符、管理with块中的上下文等。您可以将数据模型视为使用 Python 语言本身作为框架的一种方式,您创建的对象可以在其中无缝集成。

第二个原因是,它比更容易阅读和书写,Guido van Rossum 的这句名言就是支持这一观点的。len(s)`s.len()`

该符号len(s)与带前缀符号的一元运算符一致,例如abs(n).len()的使用频率远远高于abs(),因此它应该同样易于书写。

也可能有历史原因:在 Python 之前的 ABC 语言中(并且在其设计中非常有影响力),有一个一元运算符写为#swhich 表示len(s)

解决方案 4:

有一个len方法:

>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
<method-wrapper '__len__' of str object at 0x02005650>

解决方案 5:

met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.

解决方案 6:

其余答案中缺少了一些东西:len函数检查方法__len__是否返回非负数int。事实上,这len是一个函数,这意味着类不能覆盖此行为以避免检查。因此,len(obj)给出了无法达到的安全级别obj.len()

例子:

>>> class A:
...     def __len__(self):
...         return 'foo'
...
>>> len(A())
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    len(A())
TypeError: 'str' object cannot be interpreted as an integer
>>> class B:
...     def __len__(self):
...         return -1
... 
>>> len(B())
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    len(B())
ValueError: __len__() should return >= 0

当然,可以len通过将函数重新分配为全局变量来“覆盖”该函数,但这样做的代码比覆盖类中的方法的代码更明显可疑。

解决方案 7:

这里有一些很棒的答案,因此在我给出自己的答案之前,我想强调一下我在这里读过的一些精彩内容(无意双关)。

  • Python 不是一种纯粹的 OOP 语言——它是一种通用的、多范式语言,允许程序员使用他们最喜欢的范式和/或最适合他们的解决方案的范式。

  • Python 具有一等函数,因此len实际上是一个对象。另一方面,Ruby 没有一等函数。因此len函数对象有自己的方法,您可以通过运行来检查dir(len)

如果您不喜欢这种在您自己的代码中的工作方式,您可以使用您喜欢的方法轻松地重新实现容器(见下面的示例)。

>>> class List(list):
...     def len(self):
...         return len(self)
...
>>> class Dict(dict):
...     def len(self):
...         return len(self)
...
>>> class Tuple(tuple):
...     def len(self):
...         return len(self)
...
>>> class Set(set):
...     def len(self):
...         return len(self)
...
>>> my_list = List([1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'])
>>> my_dict = Dict({'key': 'value', 'site': 'stackoverflow'})
>>> my_set = Set({1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'})
>>> my_tuple = Tuple((1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'))
>>> my_containers = Tuple((my_list, my_dict, my_set, my_tuple))
>>>
>>> for container in my_containers:
...     print container.len()
...
15
2
15
15
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3983  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2747  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   82  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   90  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   79  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用