【问题标题】:Python - implement CUSTOM "lshift" method - but not for bitarray elementsPython - 实现 CUSTOM “lshift” 方法 - 但不适用于位数组元素
【发布时间】:2026-01-23 07:40:01
【问题描述】:

我有一个具有整数值参数列表的类。 我必须实现自定义 lshift 方法,该方法将添加到列表中(我必须为我的用例覆盖 lshift 方法)。这是自定义 lshift 方法,因此它没有任何与 bitarrays 相关的内容,但只能与列表中的 integers 一起使用(将其添加到列表中)并且它接收参数 element 。我应该在没有 import 额外的 python 类的情况下做到这一点。我还为这个功能定义了测试,所以你可以看到结果应该是什么样子。 (我已经为 add,len 和 iter 实现了自定义方法,但我认为这无关紧要)

class CustomShift:

    def __init__(self, iterator=None):
        self.iterator = iterator
        if (self.iterator):
            self.iterator = list(dict.fromkeys(self.iterator))

    def __lshift__(self, element):
        """Add an element to the list.

        >>> shiftInstance = CustomShift()
        >>> _ = shiftInstance << 4
        >>> sorted(shiftInstance << 5 << 6 << 4)
        [4, 5, 6]
        """
        if self.iterator is None:
            self.iterator = []
            if element:
                self.iterator.append(element)

if __name__ == "__main__":
    import doctest
    from pprint import pprint
    doctest.testmod()

前两个测试通过,但第三个失败!

TypeError: unsupported operand type(s) for <<: 'NoneType' and 'int'

不确定我做错了什么,任何提示将不胜感激。 提前致谢

【问题讨论】:

    标签: python python-3.x list class doctest


    【解决方案1】:

    首先,__lshift__ 需要返回一个值——即使它改变了它正在处理的实例。为了使链接以您期望的方式工作,它必须返回自身。由于第一个 &lt;&lt; 操作不返回任何内容,任何后续操作都将导致您提到的 TypeError 异常。

    其次,__lshift__ 方法存在逻辑错误 - 只有当 iterator 参数为 None 时才会附加元素。因此,在您想要的最一般用例中,实际上什么都不会发生。

    最后,在您的测试用例中,您想对对象调用 sort ,这意味着该对象需要提供某种迭代器(通过__iter__),否则它将简单地失败并返回TypeError: 'CustomShift' object is not iterable。将这些放在一起,您的课程将如下所示:

    class CustomShift:
    
        def __init__(self, iterator=None):
            self.iterator = iterator
            if (self.iterator):
                self.iterator = list(dict.fromkeys(self.iterator))
    
        def __lshift__(self, element):
            """Add an element to the list.
    
            >>> shiftInstance = CustomShift()
            >>> _ = shiftInstance << 4
            >>> sorted(shiftInstance << 5 << 6 << 4)
            [4, 5, 6]
            """
            if self.iterator is None:
                self.iterator = []
            if element:
                self.iterator.append(element)
            return self
    
        def __iter__(self):
            return iter(self.iterator)
    

    但是,测试仍然会失败,因为按照它的结构,shiftInstance 已经附加了一个 4,它被分配给了 _

    Failed example:
        sorted(shiftInstance << 5 << 6 << 4)
    Expected:
        [4, 5, 6]
    Got:
        [4, 4, 5, 6]
    

    然而,这应该让你朝着你可能希望如何从你所得到的东西继续前进的方向前进。

    【讨论】:

    • 你能详细解释一下这个“_”的用途是什么吗?这条线实际上做了什么_ = shiftInstance
    • _ 来自您的测试示例。对于 __lshift__ 操作的返回值,它可以替换为该分配的任何其他名称(在您的情况下,它是实例本身)。
    • 我将您的回答标记为回复。是的,我另外过滤了它,我已经有了可迭代的功能,我只是不确定它是否与此相关。我只是对测试示例“”中的那个符号感到困惑。好的,因此只需要使用任何名称作为返回值。但是为什么第三个测试没有像 " = sorted(shiftInstance
    • 哦,在 doctest 中赋值是必要的,以避免由执行语句产生的任何返回值产生输出。换句话说,通过语句 _ = ... 的赋值在典型代码中并不是绝对必要的,但如果它不存在,则 doctest 将期望将该输出与文档中的任何内容相匹配。
    最近更新 更多