len()和.__ len __()之间的区别?
调用len([1,2,3])
或[1,2,3].__len__()
之间是否有区别? 如果没有明显的区别,幕后的做法是不同的?
len
是一个获取集合长度的函数。 它通过调用对象的__len__
方法来工作。 __something__
属性是特殊的,通常不仅仅是满足眼睛,一般不应该直接调用。
早在某个时候就已经决定,把某个东西的长度作为一个函数而不是一个方法代码,推理len(a)
的含义对初学者来说是清楚的,但是a.len()
不会那么清楚。 当Python开始时, __len__
甚至不存在,而len
是一种特殊的东西,可以用于几种types的对象。 无论我们离开的情况是否完全合理,都留在这里。
通常情况下,内置或运算符的“典型”行为是调用(使用不同的和更好的语法)合适的魔术方法(名称类似__whatever__
)。 通常内置或运算符具有“附加价值”(根据所涉及的对象可以采用不同的path) – 对于len
和__len__
,只是对缺less的内置进行了一些理智的检查从神奇的方法:
>>> class bah(object): ... def __len__(self): return "an inch" ... >>> bah().__len__() 'an inch' >>> len(bah()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object cannot be interpreted as an integer
当你看到一个对内置len
的调用时,你确定 ,如果程序在这之后继续,而不是引发一个exception,调用返回一个整数,非负数,小于2 ** 31 -当你看到对xxx.__len__()
的调用时,你没有把握(除了代码的作者是不熟悉Python或不好的;-)。
除了简单的健全性检查和可读性外,其他内置插件还提供了更多附加值。 通过统一devise所有的Python,通过调用内置函数和使用操作符来工作,决不会通过调用魔术方法,避免程序员记住哪种情况是由哪个负担造成的。 (有时一个错误会导致:直到2.5,你必须在2.6中调用foo.next()
– 虽然这对于向后兼容仍然有效,你应该调用next(foo)
,在3.*
,魔术方法是正确命名为__next__
而不是“oops-ey”! – )。
所以一般规则应该是永远不要直接调用魔术方法(但总是间接通过内置的方法),除非你确切地知道为什么你需要这样做(例如,当你在子类中重写这样的方法,如果子类需要遵循必须通过显式调用魔术方法来完成的超类)。
你可以把len()看成大致等价于
def len(x): return x.__len__()
一个好处是,它可以让你写东西
somelist = [[1], [2, 3], [4, 5, 6]] map(len, somelist)
代替
map(list.__len__, somelist)
要么
map(operator.methodcaller('__len__'), somelist)
虽然有一些不同的行为。 例如在int的情况下
>>> (1).__len__() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'int' object has no attribute '__len__' >>> len(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'int' has no len()
你可以检查Pythond文档 :
>>> class Meta(type): ... def __getattribute__(*args): ... print "Metaclass getattribute invoked" ... return type.__getattribute__(*args) ... >>> class C(object): ... __metaclass__ = Meta ... def __len__(self): ... return 10 ... def __getattribute__(*args): ... print "Class getattribute invoked" ... return object.__getattribute__(*args) ... >>> c = C() >>> c.__len__() # Explicit lookup via instance Class getattribute invoked 10 >>> type(c).__len__(c) # Explicit lookup via type Metaclass getattribute invoked 10 >>> len(c) # Implicit lookup 10
- pylotly python:完全免费的?
- 在C#中embeddedIronPython的问题(缺less编译器所需的成员“Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember”
- 如何检查numpy / scipy中的blas / lapack链接?
- Thrift,Protocol Buffers,JSON,EJB等性能比较?
- Python for-in循环前面有一个variables
- Python链接列表
- 一个网站可以检测到当你使用selenium与铬酸盐?
- 如何将string拆分为字符数组?
- 如何检查variables是否与Python 2和3兼容的string