从另一个对象分配__len __()方法

时间:2013-03-01 14:15:02

标签: python python-2.7 python-3.x

我将实现一些容器对象。

class A:
    def __init__(self, L):
        self.L = list(L)
    def __len__(self):
        return len(self.L)

class B:
    def __init__(self, L):
        self.L = list(L)
        self.__len__ = self.L.__len__

在第一种情况下,同时处理len().__len__()

>>> a = A(range(10))
>>> a.__len__()
10
>>> len(a)
10

但在第二种情况下,我收到len()的错误。

>>> b = B(range(10))
>>> b.__len__()
10
>>> len(b)
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    len(b)
TypeError: object of type 'B' has no len()
  1. 为什么第二种情况下的len()不起作用,而.__len__()已定义且正常工作?
  2. 通常可以将一些方法从一个对象分配到另一个对象吗?就像我对self.L.__len__()所做的那样。

2 个答案:

答案 0 :(得分:3)

你不能这样做,像__len__这样的特殊钩子方法总是在类型上查找,而不是在实例上查找。

换句话说,len(ob)调用type(ob).__len__(ob)不是 ob.__len__()

Special method lookup documentation;我解释了为什么这是in a previous answer

对于特殊挂钩(以双下划线开头和结尾)的方法,您可以自由地为您的实例分配方法,没有技术原因阻止您这样做。

如果您的目标是通过各种方式提供facade object,请复制方法。我认为没有明显的缺点。直接在您的实例上调用方法而不必通过包装器方法进行路由会稍微好一些(为包装器方法保存堆栈推送和弹出)。

答案 1 :(得分:2)

The fine Python documentation告诉我们

  

对于新式类,只保证在对象的类型上定义特殊方法的隐式调用才能正常工作,而不是在对象的实例字典中。