不明白为什么`__index__`方法有效

时间:2016-04-18 13:40:33

标签: python

我正在使用具有以下二进制类的tutorial

import collections

class Binary:
    def __init__(self, value=0):
        if isinstance(value, collections.Sequence):
            if len(value) > 2 and value[0:2] == '0b':
                self._value = int(value, base=2)
            elif len(value) > 2 and value[0:2] == '0x':
                self._value = int(value, base=16)
            else:
                self._value = int(''.join([str(i) for i in value]), base=2)
        else:
            try:
                self._value = int(value)
                if self._value < 0:
                    raise ValueError("Binary cannot accept negative numbers. Use SizedBinary instead")
            except ValueError:
                raise ValueError("Cannot convert value {} to Binary".format(value))

    def __int__(self):
        return self._value

当使用pytest运行unittest时,我们得到:

    def test_binary_hex():
        binary = Binary(6)
>       assert hex(binary) == '0x6'
E       TypeError: 'Binary' object cannot be interpreted as an integer

要解决这个问题,文章指出:

  

根据官方文档,&#34;如果x不是Python int对象,则必须定义一个返回整数的__index__()方法。&#34;所以这就是我们所缺少的。至于__index__(),文档说明&#34;为了拥有一个连贯的整数类型类,定义__index__()时还应该定义__int__(),并且两者都应该返回相同的。值&#34;

所以我们只需要添加

def __index__(self):
    return self.__int__()

这确实有效,但为什么这里写的__index____int__会返回相同的值?关于:

def __index__(self):
    return self.__int__()

不应该是:     return self._value。__int__()

编辑:

使用:

    def __int__(self):
        return self._value

这对我有意义,因为_value是一个整数。

使用:

def __index__(self):
    return self.__int__()

在这种情况下,self又是一个类的实例,理论上它可以有很多属性(虽然不是在这种情况下)。我不明白如何回报自我。__int__(),如果我们没有明确通过__int__(),则_value知道将整数存储在_value中到__int__()

1 个答案:

答案 0 :(得分:2)

self._value是一个int,在int上调用__int__()方法返回相同的值,所以写:

return self._value.__int__()

会做同样的事情:

return self._value

只是为了证明我的观点,它将与:

相同
return int(int(int(int(self._value))))

在大多数情况下,您可以将__index__写为同一函数的直接别名:

def __int__(self):
    return self._value
__index__ = __int__

P.S。您可能需要查看PEP 357以了解__index__方法存在的原因。

基本上是区分可以转换为int的对象和本质上是整数的对象:

>>> int(1.3)
1
>>> hex(1.3)
Traceback (most recent call last):
  File "<pyshell#55>", line 1, in <module>
    hex(1.3)
TypeError: 'float' object cannot be interpreted as an integer