我知道python具有用于确定字符串大小的len()函数,但是我想知道为什么它不是字符串对象的方法。
更新
好吧,我意识到我很尴尬地犯了错误。 __len__()实际上是字符串对象的方法。 在字符串对象上使用len函数在Python中看到面向对象的代码似乎很奇怪。 此外,将__len__作为名称而不只是len也很奇怪。
字符串确实具有长度方法:__len__()
Python中的协议是在具有一定长度并使用内置len()函数的对象上实现此方法,该函数为您调用该函数,类似于您实现__iter__()并使用内置对可迭代对象执行功能(或在后台调用方法)。
有关更多信息,请参见模拟容器类型。
这是有关Python协议主题的好书:Python和最小惊讶原则
令我惊讶的是使用len的原因多么愚蠢。他们认为,强迫人们实施.__len__比强迫人们实施.len()容易。它是同一件事,看起来更干净。如果该语言将具有OOP __len__,那么制作len(..)的意义是什么
len,str等可与高阶函数(例如map,reduce和filter)一起使用,而无需定义函数或lambda来调用方法。即使在Python中,并非所有事物都围绕OOP旋转。
而且,通过使用协议,他们可以提供实现事物的替代方法。例如,您可以使用__iter__或仅使用__getitem__创建一个可迭代的对象,而iter(x)将以任何一种方式工作。您可以使用__bool__或__len__创建一个布尔可用上下文对象,而bool(x)将以两种方式工作。等等。我认为Armin在链接后的文章中对此进行了很好的解释-但即使他没有这么做,但由于一个经常公开与核心开发人员发生分歧的人的外部解释,称Python为moronic是不公平的……
@Evicatos:+1表示"不是所有的事情都围绕OOP进行,"但以"尤其是Python语言"结尾,甚至没有。 Python(与Java,Ruby或Smalltalk不同)没有尝试成为"纯OOP"语言。其明确设计为"多范式"语言。列出可迭代对象的理解方法。 zip是顶级函数,而不是zip_with方法。等等。仅仅因为一切都是对象,并不意味着成为对象是每件事最重要的事情。
那篇文章写得太差了,在尝试阅读之后,我感到困惑和愤怒。"例如,在Python 2.x中,元组类型不会公开任何非特殊方法,但是您可以使用它来创建字符串:"整个过程是几乎难以理解的句子的组合。
说出您的意愿,但len("__len__") is not"len".__len__() ...:/
@IonutBotizan不,但len("__len__") =="__len__".__len__()和len("len") =="len".__len__()。
吉姆对这个问题的回答可能会有所帮助。我在这里复制。引用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 xa + xb 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. /…/
HCI代表什么?
人机界面
这就是为什么如果您需要良好的多态性,那么请使用具有良好推理能力的语言。请参阅:转到,Haskell,CLOS。如果鸭子在屁股上咬你,鸭子打字有什么意义?
人机交互*
有一个len方法:
1
2
3
4
5>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
Python是一种实用的编程语言,len()是函数而不是str,list,dict等方法的原因是实用的。
len()内置函数直接处理内置类型:len()的CPython实现实际上返回PyVarObject C结构中表示任何可变大小的内置对象的ob_size字段的值。在记忆中。这比调用方法快得多-无需进行属性查找。获取集合中项目的数量是一种常见的操作,并且必须有效地用于诸如str,list,array.array等的基本和多种类型。
但是,为了提高一致性,将len(o)应用于用户定义的类型时,Python调用o.__len__()作为后备。 __len__,__abs__和Python数据模型中记录的所有其他特殊方法使创建类似于内置对象的对象变得容易,从而启用了表达性和高度一致的API(称为" Pythonic")。
通过实现特殊的方法,您的对象可以支持迭代,重载infix运算符,在with块中管理上下文等。您可以将数据模型视为使用Python语言本身作为可集成您创建的对象的框架的一种方式无缝连接。
第二个原因是像这样的引用来自Guido van Rossum的引用所支持的,这是因为len(s)的读取和写入比s.len()容易。
表示法len(s)与带有前缀表示法的一元运算符(如abs(n))一致。与abs()相比,len()的使用频率更高,并且应该易于编写。
可能还有一个历史原因:在Python之前的ABC语言中(在其设计中很有影响力),有一个写为#s的一元运算符,表示len(s)。
1
2met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.
处理对象时,显而易见的事情当然就是方法。
@Peter:Id向有照片证据的任何人支付20美元,以证明他们将您的评论录音带回Guidos。如果额头上有$ 50,则为$ 50。
是的,Python设计师坚持教条,但他们自己不尊重自己的教条。
$ python -c导入此| grep很明显
这里有一些很好的答案,因此在我给出自己的名字之前,我想重点介绍一下我在这里读过的一些宝石(无红宝石双关语)。
Python并不是一种纯粹的OOP语言,它是一种通用的多范式语言,它允许程序员使用他们最熟悉的范式和/或最适合其解决方案的范式。
Python具有一流的功能,因此len实际上是一个对象。另一方面,Ruby没有一流的功能。因此,len函数对象具有它自己的方法,可以通过运行dir(len)进行检查。
如果您不喜欢此代码在自己的代码中的工作方式,那么使用首选方法重新实现容器是很简单的(请参见下面的示例)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29>>> 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
你也可以说
1
2
3>> x = 'test'
>> len(x)
4
使用Python 2.7.3。
len函数已在前面的答案中提到。那么,这个"答案"有什么意义呢?
不是吗
1
2>>>"abc".__len__()
3
这应该是对这个问题的评论。现在,这只是多余的。