我能否覆盖Python列表显示?

3
我希望改变Python列表显示的行为,使其产生我编写的list子类,而不是产生一个普通的list。(注意:我认为这不是一个好主意;我只是出于兴趣而做。)
以下是我的操作步骤:
old_list = list

class CallableList(old_list):
    def __init__(self, *args):
        old_list.__init__(self)
        for arg in args:
            self.append(arg)
    def __call__(self, start, end=None):
        if end:
            return self[start:end]
        return self[start]

list = CallableList

完成这一步之后,代码将返回列表中的第三个元素:
x = list(1, 2, 3)
print x(2)

但是仍然会出现错误:
x = [1, 2, 3]
print x(2)

错误非常明显:
Traceback (most recent call last):
  File "list_test.py", line 23, in <module>
    print x(2)
TypeError: 'list' object is not callable

我认为可能没有办法做到这一点,但是我找不到任何明确说明的信息。有什么想法吗?


1
你根本不需要覆盖构造函数,因为你并没有改变列表的构造方式,你只是添加了一个方法。 - aaronasterling
3
@AaronMcSmooth:你不能为在 C 中定义的类型(如内置的 list)添加方法。 - Ignacio Vazquez-Abrams
__init__ 不是应该返回新对象吗? - badp
不,它只是初始化它,正如其名称所示。 - JasonFruit
3个回答

3

您无法轻易地覆盖内置类型使用的语法糖,因为这是在编译器级别上发生的。始终显式调用构造函数。


这是正确的。另外,似乎你正在寻找的是list.getitem(x):L.getitem(x) <==> L[x]。 - inspectorG4dget

1

你无法在Python内部更改它。 诸如列表推导之类的结构始终使用内置的列表类型,而不是您在当前命名空间中定义为list的任何内容。 如果要更改内置类型,则必须编辑Python源代码并重新编译。 假设您正在使用CPython实现,它位于Objects/listobject.c


或者你可以用Python编写自己的编译器。Python确实提供了相应的功能。 - Ignacio Vazquez-Abrams

-1
   >>> print(x(2)) # works in 2.7
   3
   >>> type(x)
   <class '__main__.CallableList'>
   >>> y = [1,2,3]
   >>> type(y)
   <type 'list'>

所以你并没有真正重新定义类型 'list',你只是改变了你的命名空间,使得类型 list 的 list() 方法现在与你的类型 CallableList 类型发生冲突。为了避免这种情况,

   >>> fred = CallableList
   >>> type(fred)
   <type 'type'>
   >>> x = fred(1,2,3)
   >>> x
   [1, 2, 3]
   >>> print x(2)
   3
   >>> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接