Negative array indicies and slice()
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Mon Oct 29 20:02:25 EDT 2012
On Mon, 29 Oct 2012 08:42:39 -0700, Andrew Robinson wrote:
>>> But, why can't I just overload the existing __getitem__ for lists and
>>> not bother writing an entire class?
You say that as if writing "an entire class" was a big complicated
effort. It isn't. It is trivially simple, a single line:
class MyList(list):
...
plus the __getitem__ definition, which you would have to write anyway. It
is a trivial amount of extra effort.
>> You can just overload that one method in a subclass of list. Being
>> able to monkey-patch __getitem__ for the list class itself would not be
>> advisable, as it would affect all list slicing anywhere in your program
>> and possibly lead to some unexpected behaviors.
>
> That's what I am curious about.
> What unexpected behaviors would a "monkey patch" typically cause?
What part of "unexpected" is unclear?
Monkey-patching is poor programming technique because it leads to
*unexpected* and *impossible to predict* interactions between *distant*
parts of the code. It leads to impossible to predict differences between
the source code on disk and the actual running code. It leads to
impossible to predict differences between documented behaviour and actual
behaviour.
Let me see if I can illustrate a flavour of the sort of things that can
happen if monkey-patching built-ins were allowed.
You create a list and print it:
# simulated output
py> x = [5, 2, 4, 1]
py> print(x)
[1, 2, 4, 5]
What? How did that happen? That's not the list you provided. The order
has been lost.
So you dig deep into your code, and you don't find anything. And you read
the Python documentation for lists, and don't find anything. And you
google the Internet, and don't find anything. And you ask for help, and
everybody says you're crazy because when they duplicate your code they
get the expected behaviour. And you report a bug in Python, and it gets
closed as "cannot replicate".
Finally you search deep into the libraries used in your code, and *five
days later* discover that your code uses library A which uses library B
which uses library C which uses library D which installs a harmless
monkey-patch to print, but only if library E is installed, and you just
happen to have E installed even though your code never uses it, AND that
monkey-patch clashes with a harmless monkey-patch to list.__getitem__
installed by library F. And even though each monkey-patch alone is
harmless, the combination breaks your code's output.
Python allows, but does not encourage, monkey-patching of code written in
pure Python, because it sometimes can be useful. It flat out prohibits
monkey-patching of builtins, because it is just too dangerous.
Ruby allows monkey-patching of everything. And the result was predictable:
http://devblog.avdi.org/2008/02/23/why-monkeypatching-is-destroying-ruby/
--
Steven
More information about the Python-list
mailing list