为什么Python中的字典和列表无法继承'len'函数
例子:
a_list = [1, 2, 3] a_list.len() # doesn't work len(a_list) # works
Python是(非常)面向对象的,我不明白为什么对象不继承" len"功能。
另外,我一直在尝试错误的解决方案,因为它对我来说似乎是合乎逻辑的解决方案
解决方案
回答
也许我们在寻找__len__
。如果该方法存在,则len(a)调用它:
>>> class Spam: ... def __len__(self): return 3 ... >>> s = Spam() >>> len(s) 3
回答
事实并非如此。
但是,我们可以执行以下操作:
>>> [1,2,3].__len__() 3
在类中添加__len __()方法是使len()神奇发挥作用的原因。
回答
好吧,实际上有一个length方法,它只是隐藏的:
>>> a_list = [1, 2, 3] >>> a_list.__len__() 3
内置len()函数似乎只是对对象的隐藏len()方法的调用的包装器。
尽管不确定为什么他们决定以这种方式实现事物。
回答
Guido的解释在这里:
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. /…/
回答
简短的答案是:1)向后兼容,以及2)差异不足以使其真正重要。有关更详细的说明,请继续阅读。
这种操作的惯用Python方法是特殊方法,不能直接调用。例如,要使x + y为自己的类工作,我们可以编写一个__add__方法。为了确保int(spam)
可以正确转换自定义类,请编写__int__
方法。为了确保len(foo)
做得很明智,编写一个__len__
方法。
这就是Python一直以来的状况,而且我认为对于某些事情来说,这很有意义。特别是,这似乎是实现操作符重载的明智方法。至于其余的,不同的语言是不同的。在Ruby中,我们可以通过直接调用spam.to_i
而不是说int(spam)
来将某些内容转换为整数。
没错,Python是一种极其面向对象的语言,必须在对象上调用外部函数以获取其长度似乎很奇怪。另一方面," len(silly_walks)"并不比" silly_walks.len()"更繁重,Guido表示他实际上更喜欢它(http://mail.python.org/pipermail/python- 3000 / 2006-November / 004643.html)。
回答
这种方式更适合其他语言。 python中的约定是,我们向对象添加__foo__特殊方法以使它们具有某些功能(而不是例如从特定的基类派生)。例如,一个对象是
- 如果具有__call__方法,则可以调用
- 如果有一个__iter__方法,则是可迭代的,
- 如果[]具有
__getitem__
和__setitem__
,则支持通过[]访问。 - ...
这些特殊方法之一是__len__,它具有可通过len()访问的长度。
回答
下面有一些很好的信息,说明为什么某些事物是函数而其他事物是方法。确实确实导致了语言上的某些不一致。
http://mail.python.org/pipermail/python-dev/2008-January/076612.html