2015-11-04 77 views
3

直观上,List类应该实现一个属性或方法来检索实例的长度。幸运的是Python'lists有一个叫做__len__的隐藏方法。不幸的是,这种方法并不是直接使用。我应该使用一个外部函数来为我读取隐藏的方法。Python中foo .__ x__和x(foo)的原因(即len和__len__)

这就像我需要问别人打开冰箱为我抢啤酒。啤酒在冰箱里,我有双手,我应该可以自己做。

从概念上讲,这种方法似乎很好奇。为什么不有一个属性(而不是一个方法)来获取列表的长度。

换句话说,我宁愿使用foo.len而不是foo.len()foo.__len__len(foo)对我来说显得更加古怪。

对此实现有解释吗?

这个answer部分回答了我的问题,但我的沮丧依然存在。

+1

[This](http://effbot.org/pyfaq/why-does-python-use-methods-for-some-functionality-eg-list-index-but-functions-for-other-eg-len -list.htm)可能值得阅读。 –

+1

以及[this one](http://lucumr.pocoo.org/2011/7/9/python-and-pola/)(花费一些时间再次查找)。 –

+0

@MathiasEttinger这两篇文章回答了我的问题。我理解背后的哲学,我必须处理它。 – nowox

回答

4

你可以找到一个深刻的理由here和圭多的想法here

总结,这是因为它们可能不像您想象的那样密切相关。只是在讨论您的帖子的len__len__,但您可以在第一个链接中找到其他示例。

class Test1: 
    pass 

class Test2: 
    def __bool__(self): 
     return False 

class Test3: 
    def __len__(self): 
     return 0 

t1 = Test1() 
t2 = Test2() 
t3 = Test3() 

现在是什么t1t2¹,并t3在布尔环境评价:通过专注于__len__

让我们开始?

  • bool(t1)True。标准的python行为,任何不明确的False被认为是True
  • bool(t2)False。明确地将对象设置为False的行为相应。
  • bool(t3)False。由于t3 implements __len__被认为是一个容器,因为它的长度是0那么它是一个空的。根据定义,一个空容器在布尔上下文中被认为是False

__len__不被绑定只能被len调用。

len,在另一方面,为您提供担保:

  • 它会返回一个正整数;
  • 它可以在任何容器上工作,不仅仅是列表;
  • 它将计算该容器中元素的数量。不管它的意思是依赖于容器,但:比较

    s = "A string with " 
    d = s.encode("utf-8") 
    print(len(s)) # outputs 15 
    print(len(d)) # outputs 18 
    

    因为s是字符的容器和d是一个字节的容器。


¹注意__bool__在python2 __nonzero__

相关问题