为什么Python代码使用len()函数而不是length方法?
我知道python有一个__len__()函数,用于确定字符串的大小,但我想知道为什么它不是字符串对象的方法。
更新
好吧,我意识到我很尴尬。 __len__()实际上是一个字符串对象的方法。 使用字符串对象上的len函数在Python中看到面向对象的代码似乎很奇怪。 此外,看到__len__作为名称而不仅仅是len也很奇怪。
8个解决方案
167 votes
字符串确实有一个长度方法:__iter__()
Python中的协议是在具有长度的对象上实现此方法,并使用内置的__iter__()函数,它为您调用它,类似于您实现__iter__()的方式并使用内置的iter()函数(或具有 对于可迭代的对象,在幕后调用的方法。
有关更多信息,请参阅模拟容器类型。
以下是关于Python协议主题的很好的阅读:Python和最小惊讶原则
Jonny Buchanan answered 2019-03-23T18:03:31Z
83 votes
吉姆对这个问题的回答可能有所帮助; 我把它复制在这里。 引用Guido van Rossum:
首先,为了HCI的原因,我选择了len(x)而不是x.len()(def __len __()来得晚了)。 实际上有两个相互交织的原因,都是人机交互:
(a)对于某些操作,前缀表示法只比读后缀更好 - 前缀(和中缀!)操作在数学中有悠久的传统,它喜欢视觉效果帮助数学家思考问题的符号。 比较我们将x *(a + b)这样的公式重写为xa + xb的简单性与使用原始OO表示法做同样事情的笨拙。
(b)当我阅读len(x)代码时,我知道它是在询问某些东西的长度。 这告诉我两件事:结果是一个整数,参数是某种容器。 相反,当我读取x.len()时,我必须知道x是某种实现接口的容器,或者是从具有标准len()的类继承的。 当没有实现映射的类具有get()或keys()方法,或者不是文件的类具有write()方法时,见证我们偶尔会遇到的混淆。
用另一种方式说同样的事情,我认为'len'是一种内置操作。 我不想失去那个。/....../
Federico A. Ramponi answered 2019-03-23T18:04:29Z
36 votes
有一个len方法:
>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
unmounted answered 2019-03-23T18:04:55Z
29 votes
Python是一种实用的编程语言,#s作为函数而不是len(s),len(),abs()等方法的原因是实用的。
#s内置函数直接处理内置类型:len(s)的CPython实现实际上返回#s C结构中的len()字段的值,该结构表示内存中任何可变大小的内置对象。 这比调用方法快得多 - 不需要进行属性查找。 获取集合中的项目数是一项常见操作,必须能够有效地处理abs(),list,array.array等基本和多样化类型。
但是,为了提高一致性,在将#s应用于用户定义类型时,Python将调用len(s)作为后备。 len(),abs()以及Python数据模型中记录的所有其他特殊方法可以轻松创建行为类似于内置函数的对象,从而实现我们称之为“Pythonic”的富有表现力且高度一致的API。
通过实现特殊方法,您的对象可以支持迭代,重载中缀运算符,管理#s块中的上下文等。您可以将数据模型视为一种使用Python语言本身作为框架的方式,您可以无缝地集成您创建的对象。
第二个原因,由Guido van Rossum引用的支持,就像这一个,它更容易读写#s而不是len(s)。
符号#s与带有前缀表示法的一元运算符一致,如len(s). len()的使用方式比abs()更常用,并且它应该像编写一样容易。
可能还有一个历史原因:在Python之前的ABC语言中(并且在其设计中非常有影响力),有一个一元运算符写为#s,这意味着len(s)。
Luciano Ramalho answered 2019-03-23T18:06:08Z
12 votes
met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.
Alex Coventry answered 2019-03-23T18:06:28Z
2 votes
你也可以说
>> x = 'test'
>> len(x)
4
使用Python 2.7.3。
SpanosAngelos answered 2019-03-23T18:07:01Z
1 votes
不是吗?
>>> "abc".__len__()
3
Nick Stinemates answered 2019-03-23T18:07:29Z
0 votes
这里有一些很好的答案,所以在我自己给出之前我想要突出一些宝石(没有红宝石双关语)我在这里读过。
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
Charles Addis answered 2019-03-23T18:08:21Z