是否有一个原因Pythonstring没有string长度的方法?

我知道Python有一个len()函数,用于确定一个string的大小,但我想知道为什么它不是一个string对象的方法。

更新

好吧,我意识到我很尴尬的错误。 __len__()实际上是一个string对象的方法。 在Python中使用string对象上的len函数来查看面向对象的代码似乎很奇怪。 此外,以__len__为名,而不是len。

string有一个长度方法: __len__()

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

请参阅模拟容器types以获取更多信息。

以下是关于Python中协议主题的一个很好的阅读: Python和最less惊讶的原则

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

首先,我select了len(x)over x.len()作为HCI的原因(def __len __()来得晚)。 实际上有两个相互交织的原因,HCI:

(a)对于一些操作,前缀表示法比postfix – 前缀(和中缀法)操作在math上有着悠久的传统,它们喜欢用视觉帮助math家思考问题的符号。 比较我们用x *(a + b)将公式重写为x a + x b的简单方法,以便使用原始的OO符号来执行相同的操作。

(b)当我读取len(x)的代码时,我知道它是在询问一些东西的长度。 这告诉我两件事情:结果是一个整数,参数是某种容器。 相反,当我读x.len()时,我必须已经知道x是某种实现接口的容器,或者是从具有标准len()的类inheritance而来的。 当一个没有实现映射的类有一个get()或keys()方法,或者不是一个文件的东西有一个write()方法时,见证我们偶尔会遇到的困惑。

用另一种方式说同样的事情,我认为“len”是一种内置操作。 我不想失去那个。 / …… /

有一个len方法:

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

Python是一种实用的编程语言,而len()是函数而不是strlistdict等方法的原因是实用的。

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

但是,为了提高一致性,将len(o)应用于用户定义的types时,Python将o.__len__()作为后备。 __abs____abs__以及Python数据模型中logging的所有其他特殊方法可以轻松创build类似于内置__abs__对象,从而实现了我们称之为“Pythonic”的expression式和高度一致的API。

通过实现特殊的方法,你的对象可以支持迭代,重载中缀运算符,pipe理块中的上下文等等。你可以把数据模型看作一种使用Python语言本身作为一个框架,你可以无缝地集成你创build的对象。

第二个原因是,像Guido van Rossum这样的引用得到了支持,读取和写入len(s)s.len()更容易。

符号len(s)与带有前缀符号的一元运算符abs(n)abs(n)len()abs()更经常使用,而且它应该很容易编写。

也可能有一个历史原因:在Python之前的ABC语言(并且在其devise中非常有影响力)中,有一个一元运算符写成#s ,意思是len(s)

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

你也可以说

 >> x = 'test' >> len(x) 4 

使用Python 2.7.3。

它不?

 >>> "abc".__len__() 3 

这里有一些很好的答案,所以在我给我自己之前,我想强调一些gem(没有ruby双关语意)我读过这里。

  • Python不是一种纯粹的OOP语言,它是一种通用的多范式语言,允许程序员使用他们最适合的范例和/或最适合他们解决scheme的范例。
  • 函数具有一stream的function,所以len实际上是一个对象。 另一方面,Ruby不具备头等function。 所以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