Python 是否存在len(someObj)不调用someObj';s_______函数?

Python 是否存在len(someObj)不调用someObj';s_______函数?,python,magic-methods,Python,Magic Methods,是否存在len(someObj)不调用someObj的\uuu len\uuu函数的情况 最近,为了(成功地)加速一些代码,我将前者替换为后者。我想确保在某个地方不存在某种边缘情况,len(someObj)与someObj不一样。len(someObj)根据Mark Pilgrim的说法,它看起来不一样。len(someObj)与someObj是一样的。 干杯 我认为答案是它将始终有效——根据Python文档: __len__(self): 调用以实现内置函数len()。应返回对象的长度,整数

是否存在
len(someObj)
不调用someObj的
\uuu len\uuu
函数的情况


最近,为了(成功地)加速一些代码,我将前者替换为后者。我想确保在某个地方不存在某种边缘情况,
len(someObj)
someObj不一样。
len(someObj)

根据Mark Pilgrim的说法,它看起来不一样。
len(someObj)
someObj是一样的。


干杯

我认为答案是它将始终有效——根据Python文档:

__len__(self):

调用以实现内置函数len()。应返回对象的长度,整数>=0。另外,一个没有定义
\uuu非零方法且
\uu len\uuu()方法返回零的对象在布尔上下文中被认为是错误的。

您看到了哪种加速?我无法想象这是显而易见的,是吗

在某些情况下,不存在 不同之处在于,使用len()是 出于几个原因,我更喜欢它

首先,不建议去 自己调用
\uuuuuuuuuuuuuuuuu方法,它们
是指供其他部分使用的
蟒蛇

len()
序列对象(
列出
元组
,以及 全部)。
\uuuu len\uuuu
将仅对使用
\uuuuuu len\uuu
方法的类实例有效

len()
将返回更合适的 无长度对象上的异常


如果
\uuuu len\uuuu
返回的长度超过
sys.maxsize
len()
将引发异常。直接调用
\uuu len\uuu
是不正确的。(事实上,您可以从
返回任何对象,除非它通过
len()
,否则不会被捕获)

在某些情况下
len(someObj)
someObj不同。
因为
len()
验证
len(someObj)
的返回值。以下是Python 3.6.9中可能出现的错误:

  • 太小,即小于0

    ValueError: __len__() should return >= 0
    
  • 太大,即大于sys.maxsize(根据具体的CPython)

  • 无效类型,例如
    float

    TypeError: 'float' object cannot be interpreted as an integer
    
  • 缺失,例如
    len(对象)

    我之所以提到这一点,是因为
    对象。
    引发了另一个异常,
    AttributeError

还值得注意的是,
range(sys.maxsize+1)
是有效的,但是它的
\uuu len\uuu()
引发了一个异常:

OverflowError: Python int too large to convert to C ssize_t

在一个运行了一分钟的程序上大约是半秒钟。可能是因为我给len打了2443519次电话。在我写问题的时候,我意识到我应该减少给len打电话的次数。@David:是的,你没有提到2443519部分。天哪;)我个人不会考虑额外的1 /第一百二十加速让代码变得丑陋,但这是你的电话。在本例中,我尝试用多种语言对同一问题进行基准测试。仅供参考:我能够删除对len的2363276个调用,这又将速度提高了一秒半。请注意,由于
len
应该返回集合中的元素数,返回大于sys.maxsize的值几乎肯定是胡说八道。@Mike理论上你可以有一个像Python 3的
范围
这样的对象,它不会将所有元素都存储在内存中,并使用数学计算其
长度<代码>范围。在这种情况下,Python int本身会引发一个错误:
范围(sys.maxsize+1)。
给出了
溢出错误:Python int太大,无法转换为C ssize\t
请注意,以上仅在2.x中是正确的。例如,在3.6中,我得到了
len(范围(10000000000))
->
10000000000
,并且(令人担忧的是)
范围(10000000000)。\uuu len()
->
-727379968
。尽管这个结果仍然说明了为什么你不应该自己调用
\uu len\uu
TypeError: object of type 'type' has no len()
OverflowError: Python int too large to convert to C ssize_t