Can literals in Python be overridden?
Question: Couldn't find a way to phrase the title better, feel free to correct.

I'm pretty new to Python, currently experimenting with the language.. I've
noticed that all built-ins types cannot be extended with other members.. I'd
like for example to add an `each` method to the `list` type, but that would be
impossible. I realize that it's designed that way for efficiency reasons, and
that most of the built-ins types are implemented in C.

Well, one why I found to override this behavior is be defining a new class,
which extends `list` but otherwise does nothing. Then I can assign the
variable `list` to that new class, and each time I would like to instantiate a
new list, I'd use the `list` constructor, like it would have been used to
create the original `list` type.

    
    
    class MyList(list):
        def each(self, func):
           for item in self:
               func(item)
    list = MyList
    
    my_list = list((1,2,3,4))
    my_list.each(lambda x: print(x))
    

Output:

    
    
    1
    2
    3
    4
    

The idea can be generalize of course by defining a method that gets a built it
type and returns a class that extends that type. Further more, the original
`list` variable can be saved in another variable to keep an access to it.

Only problem I'm facing right now, is that when you instantiate a `list` by
its literal form, (i.e. `[1,2,3,4]`), it will still use the original list
constructor (or does it?). Is there a way to override this behavior? If the
answer is no, do you know of some other way of enabling the user to extend the
built-ins types? (just like javascript allows extending built-ins prototypes).

I find this limitation of built-ins (being unable to add members to them) one
of Python's drawbacks, making it inconsistent with other user-defined types...
Overall I really love the language, and I really don't understand why this
limitation is REALLY necessary.


Answer: This is a conscientious choice from Python.

Firstly, with regards to patching inbuilt type, this is primarily a design
_decision_ and only secondarily an optimization. I have learnt from much
lurking on the Python Mailing List that monkey patching on builtin types,
although enjoyable for small scripts, serves no good purpose in anything
larger.

Libraries, for one, make certain assumptions about types. If it were
encouraged to extend default types, many libraries would end up fighting each
other. It would also discourage _making_ new types – a deque is a deque, an
ordered set is an ordered set, a dictionary is a dictionary and that should be
that.

Literal syntax is a particularly important point. If you cannot guarantee that
`[1, 2, 3]` is a list, what can you guarantee? If people could change those
behaviours it would have such global impacts as to destroy the stability of a
lot of code. There is a reason _goto_ and global variables are discouraged.

* * *

There is one particular hack that I _am_ fond of, though. When you see
`r"hello"`, this seems to be an extended literal form.

So why not `r[1, 2, 3]`?

    
    
    class ListPrefixer:
        def __init__(self, typ):
            self.typ = typ
    
        def __getitem__(self, args):
            return self.typ(args)
    
    class MyList(list):
        def each(self, func):
            return MyList(func(x) for x in self)
    
    e = ListPrefixer(MyList)
    
    e[1, 2, 3, 4].each(lambda x: x**2)
    #>>> [1, 4, 9, 16]
    

* * *

Finally, if you really want to do deep AST hacks, check out
[MacroPy](https://github.com/lihaoyi/macropy).

