Reputation: 7875
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?
Upvotes: 3
Views: 412
Reputation: 670
>>> 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
>>>
Upvotes: -1
Reputation: 76657
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.
Upvotes: 1
Reputation: 798606
You cannot trivially override the syntactic sugar used for built-in types, since this happens at the compiler level. Always call the constructor explicitly.
Upvotes: 3