views:

127

answers:

3

I'd like to change the behavior of Python's list displays so that instead of producing a list, they produce a subclass of list that I've written. (Note: I don't think this is a good idea; I'm doing it for fun, not actual use.)

Here's what I've done:

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

Once that's done, this returns the third element of the list:

x = list(1, 2, 3)
print x(2)

but this still gives an error:

x = [1, 2, 3]
print x(2)

The error is pretty straightforward:

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

I think there's probably no way of doing this, but I can't find anything that says so definitively. Any ideas?

+2  A: 

You cannot trivially override the syntactic sugar used for built-in types, since this happens at the compiler level. Always call the constructor explicitly.

Ignacio Vazquez-Abrams
This is true. Also it seems that what you are looking for is list.__getitem__(x): L.__getitem__(x) <==> L[x]
inspectorG4dget
+1  A: 

You can't change it from within Python. Constructs such as list-comprehensions always use the built-in list type, not whatever you've defined the word list to in the current namespace. If you want to change the built-in type, you have to edit the Python source code and recompile. Assuming you're using the CPython implementation, it lives in Objects/listobject.c.

Daniel Stutzbach
Or you could write your own compiler in Python. Python does provide the facilities to do so.
Ignacio Vazquez-Abrams
A: 
   >>> print(x(2)) # works in 2.7
   3
   >>> type(x)
   <class '__main__.CallableList'>
   >>> y = [1,2,3]
   >>> type(y)
   <type 'list'>

so you haven't really redefined type 'list,' you've only changed your namespace so that the type list's list() method now clashes with your type CallableList type. To avoid this,

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