arr.__len__() 是 Python 中获取数组长度的首选方法吗?[复制]

Is arr.__len__() the preferred way to get the length of an array in Python? [duplicate]

提问人:Joan Venge 提问时间:2/6/2009 最后编辑:smciJoan Venge 更新时间:4/26/2020 访问量:1701517

问:

Python 中,以下是唯一获取元素数的方法吗?

arr.__len__()

如果是这样,为什么语法很奇怪?

Python 数组 方法

评论

0赞 Vlad Bezden 10/14/2021
我在为什么 Python 的 len 函数比 __len__ 方法快

答:

1257赞 Soviut 2/6/2009 #1
my_list = [1,2,3,4,5]
len(my_list)
# 5

这同样适用于元组:

my_tuple = (1,2,3,4,5)
len(my_tuple)
# 5

还有字符串,它们实际上只是字符数组:

my_string = 'hello world'
len(my_string)
# 11

这是故意这样做的,这样列表、元组和其他容器类型或可迭代对象就不需要显式实现公共方法,相反,您可以检查实现“魔术”方法的任何内容。.length()len()__len__()

当然,这似乎是多余的,但长度检查实现可能会有很大差异,即使在相同的语言中也是如此。一个集合类型使用方法,而另一个类型使用属性,而另一个集合类型使用 ,而另一个集合类型使用 ,这种情况并不少见。使用语言级关键字可以统一所有这些类型的入口点。因此,即使您可能不认为是元素列表的对象仍然可以进行长度检查。这包括字符串、队列、树等。.length().length.count()

的功能性质也非常适合编程的功能风格。len()

lengths = map(len, list_of_containers)

评论

36赞 Tim Lesher 2/6/2009
len() 是一个全局的内置函数;__len__() 是 object 可以实现的方法。len(foo) 通常最终会调用 foo.__len__()。
1赞 ShadowRanger 9/15/2021
@BT:我怀疑至少部分原因与。 所有以双下划线(dunders)开头和结尾的名称都是:1)保留用于语言使用,以及2)允许语言绕过正常的查找规则(例如,可以直接在实例的类上查找方法,而无需检查实例是否使用同名属性对其进行了遮蔽)。CPython 引用解释器利用 #2 来加速特殊方法的隐式调用(不必通过 或 ,不必检查实例等)。__len__.length()__getattribute____getattr__dict
0赞 ShadowRanger 9/15/2021
在编译语言中,这并不重要,但在已经很慢、高度动态的解释语言中,拥有经常使用的核心概念,以便更好地优化它们,这一点很重要。长度的概念也与真实性有关,所以当你这样做时,它就会出现;CPython 可以通过 C 结构中的几个指针将其优化为 C 查找,然后如果它没有被定义,则查找 ,调用它以获得原始 C 符号,并检查结果是非零。if seq:tp_booltp_lensize_t0
0赞 ShadowRanger 9/15/2021
using 要么保留一个非保留名称来表示长度,并将优化应用于一个表面上与其他名称没有区别的名称,要么不执行此类保留和优化,明确要求,并涉及多个查找、绑定方法构造和创建 Python 级别(不仅仅是 C 级符号),即使是内置的, 使简单的“它是空的还是非空的?”测试要慢得多(快速测试将调用方法作为测试的一部分的时间延长了 4 倍以上,而不仅仅是)。.length()if seq.length():dictintsize_tlengthif seq:
26赞 Tim Lesher 2/6/2009 #2

只需使用:len(arr)

>>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1
24赞 David Locke 2/6/2009 #3

获取任何 python 对象长度的首选方法是将其作为参数传递给函数。在内部,python 将尝试调用传递的对象的特殊方法。len__len__

54赞 rz. 2/6/2009 #4

你对任何有意义的东西(列表、字典、元组、字符串等)进行长度测量的方式是调用它。len

l = [1,2,3,4]
s = 'abcde'
len(l) #returns 4
len(s) #returns 5

“奇怪”语法的原因是 python 在内部翻译为 .这适用于任何对象。因此,如果您正在定义某个类,并且它有一个长度是有意义的,只需在它上面定义一个方法,然后就可以调用这些实例。len(object)object.__len__()__len__()len

24赞 UncleZeiv 2/6/2009 #5

Python 使用鸭子类型:它不关心对象是什么,只要它有适合手头情况的接口。当你在一个对象上调用内置函数 len() 时,你实际上是在调用它的内部 __len__ 方法。自定义对象可以实现此接口,len() 将返回答案,即使该对象在概念上不是序列。

有关接口的完整列表,请查看此处:http://docs.python.org/reference/datamodel.html#basic-customization

8赞 Ahmed Abobakr 10/20/2015 #6

您可以按照前面的答案中的建议来获取数组的长度。如果您想要 2D 数组的维度,可以使用返回高度和宽度len(arr)arr.shape

7赞 Harun ERGUL 4/12/2016 #7

len(list_name)函数将 list 作为参数,并调用 list 的函数。__len__()

3赞 JOHNKYON 2/18/2019 #8

Python 建议用户使用而不是一致性,就像其他人所说的那样。但是,还有其他一些好处:len()__len__()

对于某些内置类型(如 、 等),Cython 的实现采用快捷方式。它直接返回 in a C 结构,这比调用 .liststrbytearraylen()ob_size__len__()

如果你对这些细节感兴趣,你可以阅读卢西亚诺·拉马略 (Luciano Ramalho) 的《流利的 Python》一书。其中有许多有趣的细节,可以帮助您更深入地了解 Python。