如何修复_getitem__方法

时间:2016-11-06 21:57:47

标签: python class

def pnamedtuple(type_name, field_names, mutable=False):
    pass

    class type_name:
        def __init__(self, x, y):
            self.x = x
            self.y = y
            self._fields = ['x','y']
            self._mutable = False

        def get_x(self):
            return self.x

        def get_y(self):
            return self.y

        def __getitem__(self,i):
            if i > 1 or i <0:
                raise IndexError
            if i == 0 or i == 'x':
                return self.get_x():
            if i == 1 or i == 'y':
                return self.get_y():

getitem 方法为此类重载[](索引运算符):索引0返回field_names列表中第一个字段名称的值;索引1返回field_names列表中的第二个字段名称的值等。此外,索引可以是具有指定字段的字符串。因此,对于p = Point(1,2)写入p.get_x()或p [0]),或p [&#39; x&#39;]返回结果1.使用适当的消息引发IndexError如果索引超出边界int或不指定字段的字符串。

我不确定如何修复 getitme 功能。下面是bsc.txt

c-->t1 = Triple1(1,2,3)
c-->t2 = Triple2(1,2,3)
c-->t3 = Triple3(1,2,3)
# Test __getitem__ functions
e-->t1[0]-->1
e-->t1[1]-->2
e-->t1[2]-->3
e-->t1['a']-->1
e-->t1['b']-->2
e-->t1['c']-->3
^-->t1[4]-->IndexError
^-->t1['d']-->IndexError
^-->t1[3.2]-->IndexError

有人可以告诉我如何修复我的_getitem _函数来获取bsc.txt中的输出吗?非常感谢。

3 个答案:

答案 0 :(得分:0)

您错误地拼写了__getitem__。魔术方法在它们之前和之后需要两个__下划线。

因此,您还没有超载原始的__getitem__方法,您只需创建一个名为_getitem_的新方法。

答案 1 :(得分:0)

Python 3不允许将字符串和整数与><进行比较;如果您还不知道==的类型,最好坚持使用i。您可以使用isinstance,但在这里您可以轻松地将仅有的两个有效整数值转换为字符串(反之亦然),然后只对字符串起作用。

def __getitem__(self, i):
    if i == 0:
        i = "x"
    elif i == 1:
        i = "y"

    if i == "x":
        return self.get_x()
    elif i == "y":
        return self.get_y()
    else:
        raise IndexError("Invalid key: {}".format(i))

答案 2 :(得分:0)

你的功能很有趣,但它有一些问题:

  1. 在python 3中,您无法将字符串与数字进行比较,因此您首先应使用==检查已知值和/或类型。例如

    def __getitem__(self,i):
        if i in {0,"x"}:
            return self.x
        elif i in {1,"y"}:
            return self.y
        else:
            raise IndexError(repr(i))  
    
  2. 但是对于实例t1(在您的代码或上面的示例中)进行了定义,对于除t1[X]"x"以外的所有字符串X,此"y"将始终失败因为你没有为任何其他值调整它。那是因为

  3. pnamedtuple看起来你想让它成为像collections.namedtuple这样的工厂,但它不够通用,因为你根本不使用你函数的任何参数。不,type_name也没有被使用,无论它有什么价值,当你进行类声明时它都会被丢弃。

  4. 如何解决?

    1. 您需要其他方式来存储字段的值及其各自的名称,例如字典可以将其称为self._data

    2. 要记住你如何调用你的字段,请使用你的函数的参数,例如self._fields = field_names

    3. 要接受未知数量的参数,请使用* like __init__(self, *values),然后验证您具有相同数量的值和字段,并构建第1点(字典)的数据结构

      < / LI>

      一旦准备就绪,__getitem__就会变成:

      def __getitem__(self, key):
          if key in self._data:
              return self._data[key]
          elif isintance(key,int) and 0 <= key < len(self._fields):
              return self._data[ self._fields[key] ]
          else:
              raise IndexError( repr(key) )
      

      或者您可以简单地从适当的namedtuple继承,您唯一需要做的就是覆盖其__getitem__

      def __getitem__(self,key):
          if key in self._fields:
              return getattr(self,key)
          return super().__getitem__(key)