我知道python有一个len()函数,用于确定字符串的大小,但我想知道为什么它不是字符串对象的方法?
当前回答
met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.
其他回答
Python是一种实用的编程语言,len()是一个函数而不是str, list, dict等的方法的原因是实用的。
len()内置函数直接处理内置类型:len()的CPython实现实际上返回PyVarObject C结构体中ob_size字段的值,该结构体表示内存中任何可变大小的内置对象。这比调用方法快得多——不需要进行属性查找。获取集合中的项数是一种常见操作,对于str、list、array等基本和不同的类型,必须有效地工作。数组等。
然而,为了提高一致性,当将len(o)应用于用户定义的类型时,Python调用o.__len__()作为回退。__len__, __abs__和Python数据模型中记录的所有其他特殊方法可以很容易地创建行为类似于内置的对象,从而实现我们称为“Pythonic”的具有表现力和高度一致性的api。
通过实现特殊的方法,你的对象可以支持迭代,重载中缀操作符,用块管理上下文等等。您可以将数据模型视为使用Python语言本身作为框架的一种方式,在该框架中可以无缝集成所创建的对象。
第二个原因是,读和写len(s)比s.len()更容易,这可以从Guido van Rossum的引用中得到支持。
表示法len(s)与带前缀表示法的一元运算符一致,如abs(n)。Len()比abs()使用得更频繁,而且它应该同样易于编写。
也可能有历史原因:在Python之前的ABC语言中(对Python的设计影响很大),有一个一元操作符写为#s,意思是len(s)。
吉姆对这个问题的回答可能会有所帮助;我复制在这里。引用Guido van Rossum的话:
First of all, I chose len(x) over x.len() for HCI reasons (def __len__() came much later). There are two intertwined reasons actually, both HCI: (a) For some operations, prefix notation just reads better than postfix — prefix (and infix!) operations have a long tradition in mathematics which likes notations where the visuals help the mathematician thinking about a problem. Compare the easy with which we rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of doing the same thing using a raw OO notation. (b) When I read code that says len(x) I know that it is asking for the length of something. This tells me two things: the result is an integer, and the argument is some kind of container. To the contrary, when I read x.len(), I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standard len(). Witness the confusion we occasionally have when a class that is not implementing a mapping has a get() or keys() method, or something that isn’t a file has a write() method. Saying the same thing in another way, I see ‘len‘ as a built-in operation. I’d hate to lose that. /…/
这里有一些很棒的答案,所以在我给出我自己的答案之前,我想强调一下我在这里读到的一些宝石(没有红宝石双关语的意思)。
Python不是一种纯粹的面向对象语言——它是一种通用的、多范式的语言,允许程序员使用他们最熟悉的范式和/或最适合他们的解决方案的范式。 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
字符串确实有一个length方法:__len__()
Python中的协议是在具有长度的对象上实现这个方法,并使用内置的len()函数为你调用它,类似于在可迭代的对象上实现__iter__()并使用内置的iter()函数(或在幕后为你调用该方法)。
有关更多信息,请参见模拟容器类型。
这里有一篇关于Python协议主题的很好的阅读:Python和最小惊讶原则
有一个len方法:
>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
<method-wrapper '__len__' of str object at 0x02005650>
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录