5

我有类似的数据data = [[t1, t2, ...], [v1, v2, ...]]。我想将它包装在一个类中,这样我就可以调用data.t而不必使用data[0].

我试图用以下方法做到这一点:

class Variable:
    def __init__(self, data):
        self.t = data[0]
        self.v = data[1]

    def __getitem__(self, key):
        if key == 0:
            return self.t
        elif key == 1:
            return self.v
        else:
            raise ValueError("not valid key '{}'".format(key))

    def __setitem__(self, key, value):
        if key == 0:
            self.t = value
        elif key == 1:
            self.v = value
        else:
            raise ValueError("not valid key '{}'".format(key))

__getitem__和重载的原因__setitem__是为了向后兼容,所以它data[0]仍然有效。这适用于大多数事情,但是我遇到了以下调用的问题:

func_that_takes_two_arguments(*data) # unpacking data

我得到的错误是

/Users/pingul/Workspace/lhcfill/oml.py in __getitem__(self, key)
     52                                 return self.val
     53                         else:
---> 54                                 raise ValueError("not valid key     '{}'".format(key))
     55 
     56                 def __setitem__(self, key, value):
ValueError: not valid key '2'

如何使用参数解包运算符使我的类正常工作?

4

1 回答 1

6

运算符通过*迭代对象来工作。仅通过 implementation 可以很好地执行此迭代__getitem__(),但是您的 implementation 是错误的。相反,如果 raise ValueError,您应该 throw IndexErrorwhich 表示迭代结束。

另请参阅https://docs.python.org/3/reference/datamodel.html#object。明确声明的 getitem

注意: for循环期望IndexError为非法索引引发 an 以允许正确检测序列的结尾。

https://docs.python.org/2/library/functions.html#iter声明这被称为“序列协议”。

于 2016-10-25T14:25:24.697 回答