arr .__ len __()是在Python中获取数组长度的首选方法吗?


Answers:


1228
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)

8
len()是语言命令,__ len __()是容器类型的方法。
苏联2009年

33
len()是一个全局的内置函数;__len __()是对象可以实现的方法。len(foo)通常最终会调用foo .__ len __()。
蒂姆·莱瑟

13
您提到通过提供len(),每个容器不必实现.length()方法,但是如果每种类型仍然实现__len __()方法(无论如何还是要被len()调用),这有什么不同?len()处理不同的容器类型是否有所不同?
西蒙·詹森,2009年

10
@Simon:关于“不需要全部实现.length()”的说法令人困惑。容器类型仍然需要实现一种返回其长度的方法。关键是这是一个标准化的协议,而不是您必须针对每种类型查找的临时方法。双下划线表示这一点。
卡尔·迈耶

16
我同意卡尔·迈耶(Carl Meyer)的观点-所说的“不需要显式实现”公共.length()方法具有误导性,其核心含义是不正确的。任何东西都仍然必须实现len,并且总是可以简单地实现自己的长度方法,该方法可以随意命名,而无需绕过len函数。因此,我确实认为这与Guido如何看待世界有些随意。它可能与任何通用推理都没有关系。
BT

52

取任何有意义的长度(列表,字典,元组,字符串等)的方法是调用len它。

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

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


23

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

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


23

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





1

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

对于一些内置的类型,如liststrbytearray等等,在用Cython实现len()需要一个快捷方式。它直接ob_size以C结构返回,比调用更快__len__()

如果您对这样的细节感兴趣,可以阅读Luciano Ramalho的书“ Fluent Python”。其中包含许多有趣的细节,可能有助于您更深入地了解Python。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.