There’s an old joke, so old that I don’t even know for certain where it originated, that’s often used to explain why big corporations do things the way they do. It involves some monkeys, a cage, a banana and a fire hose.
You build a nice big room-sized cage, and in one end of it you put five monkeys. In the other end you put the banana. Then you stand by with the fire hose. Sooner or later one of the monkeys is going to go after the banana, and when it does you turn on the fire hose and spray the other monkeys with it. Replace the banana if needed, then repeat the process. Monkeys are pretty smart, so they’ll figure this out pretty quickly: “If anybody goes for the banana, the rest of us get the hose.” Soon they’ll attack any member of their group who tries to go to the banana.
Once this happens, you take one monkey out of the cage and bring in a new one. The new monkey will come in, try to make friends, then probably go for the banana. And the other monkeys, knowing what this means, will attack him to stop you from using the hose on them. Eventually the new monkey will get the message, and will even start joining in on the attack if somebody else goes for the banana. Once this happens, take another of the original monkeys out of the cage and bring in another new monkey.
After repeating this a few times, there will come a moment when none of the monkeys in the cage have ever been sprayed by the fire hose; in fact, they’ll never even have seen the hose. But they’ll attack any monkey who goes to get the banana. If the monkeys could speak English, and if you could ask them why they attack anyone who goes for the banana, their answer would almost certainly be: “Well, I don’t really know, but that’s how we’ve always done things around here.”
This is a startlingly good analogy for the way lots of corporations do things: once a particular process is entrenched (and especially after a couple rounds of employee turnover), there’s nobody left who remembers why the company does things this way. There’s nobody who stops to think about whether this is still a good way to do things, or whether it was even a good idea way back at the beginning. The process continues through nothing more than inertia, and anyone who suggests a change is likely to end up viciously attacked by monkeys.
But this is also a really good analogy for the way a lot of software works: a function or a class or a library was written, once upon a time, and maybe at the time it was a good idea. Maybe now it’s not such a good idea, and actually causes more problems than it solves, but hey, that’s the way we’ve always done things around here, and who are you to suggest a change? Should I go get the fire hose?
It’s rare that any large/established software project manages to overcome this inertia and actually take stock, figure out whether “the way we’ve always done it” is still a good way to do it, and then make changes in response. This week Python 3.0 was released, and it represents one of those rare instances: Python 3.0 was designed to clear up a lot of now-inertial legacy issues with the Python language and figure out good ways to do things now instead of unquestioningly sticking with what seemed like good ways (or, more often, the least painful ways) to do things five or ten years ago.
Of course, this is causing some people to ask whether it was a good idea; all other things being equal, it’s better to maintain compatibility than to break it, and if the break doesn’t seem to offer anything really major or impressive over the previous compatible version, then it’s natural to ask what, exactly, made this necessary. Jens Afke has rather notably posted some thoughts along those lines, and this post is an attempt to respond and explain, as clearly as I can, why I think Python 3.0 is and will be a good thing even though it’ll create a staggering amount of work for me, my co-workers and my friends and colleagues (since I deal with two large Python 2.x codebases on a daily basis, the migration is not going to be simple or short for me).
I really like Python. It’s my language of choice for new projects, my language of choice for hacking up quick things to play with and the language I get to work with every day at my job. Python fits my brain in ways that no other programming language ever has, and I agree with pretty much all of the basic design philosophy behind it. And by and large, I think writing (and reading — something just as important, which too many other languages have neglected) Python is one of the more pleasant ways to code for a living.
But.
For as long as I’ve been using Python there have been little moments of pain. None of them in isolation is enough to make Python itself painful, but taken together and occasionally stumbled over, they definitely have an impact on the experience. There’s a passage in Good Omens that does a great job of approximating the effect this sort of thing has on a programmer, when compounded over a period of years. Some demons are meeting and discussing the evil things they’ve done — tempting a priest, corrupting a politician, etc. — and one of them proudly declares that he tied up a phone system for most of an hour:
What could he tell them? That twenty thousand people got bloody furious? That you could hear the arteries clanging shut all across the city? And that then they went back and took it out on their secretaries or traffic wardens or whatever, and they took it out on other people? In all kinds of vindictive little ways which, and here was the good bit, they thought up themselves? For the rest of the day. The pass-along effects were incalculable. Thousands and thousands of souls all got a faint patina of tarnish, and you hardly had to lift a finger.
Running into the warts in Python, from time to time, has much the same result: it diminishes the joy of programming in slight and subtle ways.
Working with Unicode, for example, has most likely taken years off the collective lives of Python programmers everywhere. The Universal Feed Parser, which is arguably the best feed-parsing library on the planet, pithily glosses over some of the pain in its documentation, but Beautiful Soup, which is almost certainly the best screen-scraping library on the planet, expresses the agony of Unicode handling in a way that may not comply with corporate coding style guides:
Beautiful Soup uses a class called
UnicodeDammitto detect the encodings of documents you give it and convert them to Unicode, no matter what. If you need to do this for other documents (without using Beautiful Soup to parse them), you can useUnicodeDammitby itself.
Meanwhile in the Django world, Malcolm, I’m sure, is now slightly crazier than he was before his heroic effort to make Unicode handling as painless as possible for Django applications.
Now, Unicode and character encoding in general constitute a genuinely brain-bustingly hard problem, but Python — that is, Python 2.x — did almost nothing to help with this. It had two types of strings: one for Unicode and one for strings in some particular encoding (remember: Unicode is not an encoding), and so lots of Python software which worked with text had to develop all sorts of heuristics and libraries and helpers to work out what, exactly, any given string really was and how to work with it. Even more Python software simply never bothered, which meant that you could quite easily pass a string into some module you were using and find a UnicodeDecodeError staring back at you out of the abyss.
Python 3.0 fixes this, or at least insofar as it’s possible to “fix” character encoding and Unicode handling at the language level: there’s one string type and only one string type, and that type is Unicode. No longer must you guess whether a string is either of multiple types or in any of a bewildering number of encodings (some of which may not even be supported by your copy of Python); strings are strings are strings, and that’s that. If you need to interact with systems which want sequences of bytes in some particular encoding, there’s a separate type — bytes — which lets you do that, and to go from str to bytes you have to encode the string, and to get weird non-default encodings you have to say that you’re going to use a weird non-default encoding.
If Python 3.0 introduced the new Unicode handling and no other changes whatsoever, I’d be willing to call it a win.
One of the great strengths of Python, perhaps one of its greatest strengths, is its philosophy of “batteries included”; though the Python core language is rather small, and the number of things in the built-in namespace is puny compared to some other languages, it comes with a large standard library of modules covering all sorts of things that Python programmers will need to do. But there’s a downside to this: to stay useful, good modules need to evolve over time, and sometimes need to be replaced outright, and modules which ship in the standard library can’t easily do this because of the need to preserve backwards compatibility.
As a result, the standard library for Python 2.x grew to include a strange mish-mash of oddball historical corner cases. For example:
urllib (which came first) and urllib2 (which, obviously, came second).
pickle versus cPickle, StringIO versus cStringIO, and so on.
md5 and sha, both of which are now better handled by hashlib).
Even though all these great modules were available, the fact that their organization was a bit haphazard and redundant introduced another layer of low-grade tarnish on the soul. Python 3.0 reorganized the standard library to make more sense, and even renamed a few things to fall more in line with common conventions. No longer do you first try to import a C-based version of a module and then fall back to a Python-based version. No longer do you try to import hashlib and then fall back to md5. No longer do you hunt through multiple separate but related top-level modules to find the one with the bits you need. Though small, these sorts of changes have a major long-term impact on the clarity and maintainability of any kind of significant Python codebase. And although this will involve a fair amount of migration work for large projects which use lots of libraries, it’s still a big win going forward.
Similarly, less-obvious bits are changing in significant ways; for example, Python has long had two types of classes, largely for historical reasons, and the older of the two is nowhere near as useful or flexible as the newer. For the curious, a new-style class inherits directly from object, or inherits from some other class which ultimately derives from object, while a “classic” class doesn’t. The Python 2.6 documentation covers this (and goes on, elsewhere, to list some very useful things which only work with “new-style” classes), and Python 3.0 does away with the last remaining backwards-compatible support for the old-style classes, bringing with it a logical unification and general cleanup which will be extremely welcome to this Python programmer.
Although at the start I paid only the most cursory attention to the Python 3.0 development process, every time I looked into it in any detail I was struck by the amount of time and thought which went into the changes which have been made to the language. There are, so far as I can tell, no frivolous “we just did this because we liked it” differences between Python 2.x and Python 3.x; every breaking change seems to have been discussed to death, justified based on real-world problems and even then carefully considered and reconsidered just to see if a backwards-compatible way could prevail. Python 3.0 came out of a years-long process of development by people who were simultaneously actually using Python and taking notes on how it could be better, and it shows.
Jens states in the comments to his article that he feels like the changes in Python 3.0 are “academic”, by which I assume he means “irrelevant to real developers and practical concerns”. Based on some of the examples above (and plenty more which can be found by browsing the new documentation), I hope it’s now clear that this is simply incorrect. Python has, for as long as I’ve been using it, come under continual fire from people who felt it didn’t embody some theoretical notion of purity that they cared about — Python doesn’t make threads the One True Way to do concurrency, Python doesn’t force everything to be an explicit invocation of a method on a class, Python isn’t a pure functional programming language, etc. — and over that entire time Python has steadfastly resisted the idea of purity for purity’s sake (or, more derisively, an “academic” notion of purity). As the Zen of Python makes clear, “practicality beats purity”.
Python 3.0 is and was developed to be a practical language. The changes which break compatibility with Python 2.x are in many ways small and may seem insignificant at first glance, but small changes have big effects, and a cleaned-up, less-soul-tarnishing Python is, in my opinion, a goal which justifies a few breaks between major versions.
Besides, evolving the language over time in response to practical concerns is the way they’ve always done things around here.
Comments for this entry are closed. If you'd like to share your thoughts on this entry with me, please contact me directly.
Whilst there’s little question that I’m crazier now than I was 18 months ago, that just comes with advancing years and oncoming geriatricity. The conversion of Django to handle non-ASCII bytestrings and use Unicode internally was relatively straightforward and although it took time, that’s more because there was a large historical codebase involved with a lot of string usage in it (and some outright bugs).
I can even “prove” this in some sense: here’s the plan I wrote before starting the work and I followed it pretty closely. Of course this one hints that it wasn’t all plain sailing, but that wasn’t Unicode’s fault. Email specifications and practical implementations are @#$%*^ hard (fiddly, time-consuming)!
There was one Python 2.3 bug we had to work around that took a while to rediscover (I hadn’t known it existed before doing that conversion) and some semi-hard thinking to get our lazy translation wrapper working (for values of “working” that, in hindsight, meant “about 85% correct” — it’s more like 100% these days). Sure there were some edge-case bugs that popped up, but I don’t think there was ever a time I looked at a bug and thought “I have not idea what is causing this” or “I don’t know how to fix that”.
Completely agree that it’s a poorly understood area, but that isn’t really Python’s fault. That understanding is why UnicodeDamnit exists in BeautifulSoup, not because the technology is lacking somehow; it’s a wetware problem. Python’s unicode support in the 2.x series is quite good. I like the type changes in 3.0 for string handling as well, don’t get me wrong. But let’s not give “Unicode is difficult” or any of my imagined accomplishments too much visibility here.
James: What a fantastic, historical, logical, and fact-based argument in support of Python 3.
Malcom: I disagree with your disagreement over the Unicode-was-difficult assertion. Even though it was always possible to handle encoding and decoding correctly, it wasn’t as intuitive as it could be - as it is now in Python 3. Making doing the right thing easy seems like a perfectly legitimate objective to celebrate, and Python 3 delivers.
More than one time I’ve gone looking deep inside someone else’s library to see what the (&@#! they were doing with their strings, mucking up my otherwise sane handling of same.
I’m with James and have said as much elsewhere - the Unicode support alone is worth the price of admission. It’ll make doing the right thing easy, and for most, even if they don’t fully understand it, things will just work.
James, that’s an excellent article. I’ve already printed it to store for years and return back to read again and again.
Python 3.0 is the first real implementation of PEP 20: The Zen of Python.
It’s probably the most important language clean-up efforts of modern CS era. Backward compatibility is a good thing for dependability stand point of view but as a paradox it’s a plague that spreads and infects the product in the long run; thus making it cumbersome and less dependable.
Again, thanks and congratulations for this excellent piece of content.
@Malcolm: Mostly I’m thinking in terms of the fact that, because Python had the two different types of strings, and because Web stuff in particular notoriously causes encoding headaches (and encoding — not Unicode — is a genuinely tricky problem in general), and because lots of different Python libraries all had to try to toll their own solutions to working with both Unicode and bytestrings, you ended up with a very haphazard, unpredictable mess of stuff. Every time I see things like the filters in
django.contrib.markupwhich have to round-trip text to bytestrings and back again just to pass through a library without errors, I look forward to Python 3.0 a bit more :)hey, great stuff
What do you think of their decision to not special case small integers causing the 10% speed decrease? It seems to me that API uniformity on the frontend should not necessarily prevent performance enhancing tweaks in the backend.
Excellent write-up. I love facts!
Zing! Loved the monkey story. Mentioned it in katrineholmuncensored.blogspot.com
I think it’s a case of “make it right, then make it fast”. It’s not like there’s some dictate forbidding anyone doing optimization work in 3.x releases, after all.
@Bill
10% speed decrease on a synthetic benchmark that has lots of math in it is probably not that meaningful for real Python programs, which don’t tend to spend a lot of their inner loops doing math. (Math-heavy python stuff usually outsources to extensions written in C, e.g. the numpy “Numerical Python” package.) I do a ton of numerical computing, and the math slowdown of 3.0.0 worries me not at all.
Also, note that the change was to remove some special-casing that had built up around an old system (which had two different integer types, roughly corresponding to C’s int and long int) to make it easy to transition to a new system (only longs). There’s no reason that similar-ish special casing, or something even better, won’t be added back in a post x.0.0 release, based on people’s experiences with the new codebase. In fact, the docs are pretty clear that this is in the cards. “Make it work, then make it work fast” is pretty standard software development practice, after all.
All in all, and as the article above points out in other cases, it’s best to assume with Python 3 that any decision was carefully considered, usually by people with a ton more experience with language design, implementation, and evolution, than you or I are likely to have.
I too am very happy with the 3.0 release. The only thing I am less than perfectly happy with is the new super() which actually makes me very sad.
Hi, I’m new to Python and Django. I would like to start with Python 3. Can you suggest me a good book on Python 3?
Good write-up, James. There’s obviously a bunch of code that needs to be converted over the coming months/years, but ultimately it’s a Good Thing (tm), IMHO. I don’t think Python will lose any serious momentum over this, although some people are bound to be butthurt. I wish more languages would get rid of aging crud, but Python is probably one of the few languages that can get away with it.
@Aida: Django is not expected to run on Python 3 until at least a year or two in the future. The same is true of most other useful Python software, so you will be much better off starting with Python 2.6 (which is much more compatible with 3.0 than previous 2.x releases) and then simply upgrading when the software you’re using makes the switch.
I would love to use python 3.0 on projects, but I still get stuck on bindings for some 3rd party libraries to Python 2.6. Realistically it will be at least 2 years before python 3.0 has the wide-spread kind of support needed to make it production-level useful.
I’ve admired the process leading to this release and although it may have been painful for those involved (I don’t know it was painful for sure but all that discussion must be painful, right?) it is a perfect example of how to move an entrenched technology forward. Slowly and steadily.
2 years will be a long time for this new language to emerge. If library support continues along 2.X.X branches (since they remain the most practical)and little to no work is done on 3.X branches that would be a real shame.
I heard that monkey joke in the movie “The Contender”. It’s in the outtakes of the DVD.
If you are new to Python, start with the tutorial: http://docs.python.org/3.0/tutorial/index.html. After that skim the library reference http://docs.python.org/3.0/library/index.html and bookmark the Python 3.0 documentation page http://docs.python.org/3.0/. If you know a bit of programming it will be easy to pick up Python from the web documentation.
Jens Afke’s article made me think: now is not the time to check Python (I’m kind of beginning programming); this post made me think: in a few month’s time, when an updated book gets out, will be a perfect time to check it out.
Thanks for the well-reasoned response, James! I’ve written a reaction: http://mooseyard.com/Jens/2008/12/james-bennett-“lets-talk-about-python-30”
Great article. Although I agree with many of the changes presented in Python 3.0, as a relatively new Python programmer I am regularly confused by Python’s datetime, time and calendar modules. I believe not changing the time, and datetime modules of the standard library was a huge oversight. I believe these could be combined into a single module. I almost always end up importing all three and find myself confused about the differences between them. consider: >>> import time >>> import datetime >>> time.time() == datetime.time() False
I am also frustrated with the lack of a concrete implementation of the tzinfo class, which means there is no standard Python way of letting my application know I am in PST. At work we use a database (PostgreSQL) that supports timezone aware timestamps and I often make the mistake of doing: if mydb_row.duedate < datetime.now(): which raises an exception since datetime.now() is timezone naïve. So I end up doing (which I don’t believe is in anyway intuitive): if mydb_row.duedate < datetime.now(mydb_row.duedate):
Nice article, James.
I know nothing about Python (nor programming in general) but your article conveys your enthusiasm and optimism. A fascinating insight into someone else’s world
David,
I, too, get frustrated with the date and time stuff. I often feel like I have some Lego and some Tinker Toys that need to be put together to make something. But the Lego expects a string and returns a tuple, and when I try to connect that to a Tinker Toy, it only wants a datetime object and I have to fiddle around to find a combination that works.
It’s unusual to find a programming article well-written enough to belong in the New Yorker. I appreciate it.
FYI, someone recently submitted it to digg:
http://digg.com/programming/Let_s_talk_about_Python_3_0
Thanks for this article.
Paul Graham mentions a story with a punchline similar to monkey story’s at http://www.paulgraham.com/arcll1.html :
So my friends and I now refer to something done only because “it’s always been done that way” as an “onion in the varnish”.
And yes, I’m glad to see that the python community has the will and the skill to take the onions out of the varnish recipe once they’re no longer needed.
You reminded me of why I got excited about Python in the first place, and why I should be excited about Python 3.0. Thank you.
I think this is a good article but I tend to agree with this post a lot more http://www.michaeldehaan.net/?p=793
I don’t get it. Why not create new keywords with new functionality, and slowly depreciate the old ones?
So you’re saying this would be a good time to get started in Python? :) I’ve been wanting to learn some Python for a while, but other projects have gotten in the way.
Tremendously far-sighted and well written. Thanks so much for this.
Great to see Python is actually catching up with Java! Java does Unicode handling like Python3 since the first release 1.0 from 1995.
I just want to quickly comment that this was one of most perfectly written articles I’ve read in a while. The story at the beginning, the use of examples, the witty style, the subheadings, and the tie into the original story at the very end… brilliant. Most programmers I know could never write like that. Hell, most writers probably can’t. So much of what I read on the web (especially on blogs) is written quickly and sloppily. This was refreshing.
i’ve just started using python and have found it to be greatly enhancing my ‘process.’ i am not very familiar with the differences between the versions, but i know my usage has become almost, you might say… poetic - http://web-poet.com/2008/12/07/the-lure-of-python/
The introduction was way too long. I almost quit reading at the Good Omens quote. Since this was linked from Gruber I thought maybe it was important. It turns out the only information contained in the essay is that Unicode handling was bad in 2.x versions of python (it isn’t clear it is “better” in 3.0) and that the standard library was reorganized. Steve Yegge is not a writer to emulate.
Obvious troll is obvious.
James, excellent article. Thank you.
Like Aida I’m interested in learning and using Python and Django, and I’d appreciate your advice on this point:
Is there any online resource SPECIFICALLY dealing with how to use 2.6 and Django in a way that will substantially ease transition to 3 and new Django?
Thanks. Mario
@Jeremy Ricketts Try doing UTF-16 in Java. It sucks. It’s much easier Much easier in Python.
Sorry Jeremy, I should have aimed my comment at Eduardo.
@Eduardo Try doing UTF-16 in Java. It sucks. It’s much easier Much easier in Python.
A great article. Generally, I’m very happy with Python 3.0 and applaud the efforts and hard work of the developers to improve the language, and be brave enough to do it this way.
There are still a few old warts though that remain in 3.0 that I wished could have been solved.
The datetime and time zone handling is still a mess. There’s no concrete implementation for tzinfo; although the contributed pytz module based on the public domain zoneinfo databases seems like an obvious candidate. However there are still two types of somewhat incompatible datetimes; those with time zones and those without. Furthermore, I think that when tzinfo is present the datetime implementation does things backwards. Ideally the time portion should always be unified, such as in UTC, and the tzinfo is used to compute the local time when needed. However, as is, Python’s datetime time portion is in the local time and the tzinfo says how to get it back to UTC. This causes problems, not the least of which is potential ambiguity during the daylight-to-standard transition period.
Another problem is the DB API. Granted this is a case where Python just dictates a standard API, and implementations are outside of the language. But that standard API seems more oriented to making implementations easier at the expense of making writing portable applications actually harder. Specifically the nonsense about having different kinds of SQL parameter substitution syntaxes. There should only be ONE syntax, and make the database module implementation do any translation if it needs.
Finally, I really like the separation of strings and bytes. However there are plenty of standard modules are still using strings (and now unicode strings) where the new bytes type would be more appropriate now that such a type exists.
I think your opening is brilliant and I’d just like to add a bit of evidence to your idea that people easily accept some notions based on tradition or even received experience without considering whether it’s a good idea or the basis for it. There’s an anecdote that we psychologists love to talk about. There was a woman who, when she made a ham, would cut the “butt” of the ham off. One day her mother came over for dinner and saw her cut the end of her the ham off and commented that it was an interesting technique. “Why do you do that, dear?” The woman making dinner replied to her mother, “Well, I do it because that’s how you always made the ham.” The mother replied, “Oh no, dear, our oven was just too small to fit an entire ham.”
I would like to say a “thanks”, a “great”, and another “thanks” in add of all the comments already made.
Now it really gives incentives to beginners to directly go try and learn py3k than looking recipes that handle problems which don’t exist anymore ! As I use Chinese in some scripts, all the butthurt stuff with asian characters support is gone with direct unicode handling !
Just waiting for the 3rd party libraries to get up to speed, and it will be really awesome ! I am especially waiting for an implementation of the ZODB for py3k (no SQL handling … so good !).
I’m just really disappointed that after going to all the trouble to make a backwards-incompatible update, they still didn’t change the two things that scared me away from Python towards Ruby when I first learned tried to learn it: len() being a global function and having to pass self to every method. You would think that the inconsistency of len() would be the first thing they would notice, but I guess Python programmers get so used to it after using it for a long time that they don’t see it. One of the main things that attracted me to Ruby was the monkeypatching, so that I knew that even if Ruby had made a stupid decision like a global function for what should be an instance method, I could fix Ruby myself.
Python doesn’t force everything to be a method of an object, and doesn’t shy away from delegating various common tasks to standalone polymorphic functions like
len(),sum(), etc. But perhaps Python programmers stick to it because they think it’s a good way to do things.To make the point by turning your comment on its head: the ubiquity of monkeypatching in Ruby (and monkeypatching of monkeypatching when someone else’s monkey turns a fire hose on yours, and then monkeypatching of monkeypatching of monkeypatching when the other person finds out what you’ve done, and…) frankly scares the heck out of me, but even though I’d never want to work that way I don’t necessarily think Ruby is inherently wrong for supporting it, or that Ruby programmers are somehow blinded to problems it causes; Ruby’s developers and Ruby programmers think it’s a good feature, and I can respect that. Perhaps you could offer the same respect to Python and Python programmers ;)
God said: Let there be Python 3! And there was Python three.
However, I am supporting the evolutionary approach of python. :)
http://mithrandi.vox.com/library/post/more-on-python-3.html
James Bennett:
I agree that monkeypatching can be overused, but at least it’s optional. The problem I see with len() is that it’s the enforced standard. If len() was just an alternative syntax for calling an object’s len method, I wouldn’t mind as long as people could also just say myObject.len(). But as far as I know, with the current len(), people can’t do that. (If I remember correctly, to implement len(), you make a len method that can’t be called directly. I might be wrong on that.)
You say Python doesn’t “shy away from delegating various common tasks to standalone polymorphic functions like len(), sum(), etc.” I don’t mind sum(); a global function seems as good a place to put it as any other. But len() is always a property of some object, and far from Ruby “forc[ing] everything to be a method of an object”, a method of an object is the only way I can see len() making sense.
Basically, the difference between Ruby’s possibly bad monkeypatching and Python’s possibly bad len() is that monkeypatching is optional, but everyone is forced to use len() as a global function, and I don’t see any way making it global gives better organization or more convenience.
I am a fan of python language and I welcome Python 3.0. as the next big thing in many ways.
Speed Issue
I am unhappy with Python speed as Ruby 1.9 and Java 6 are faster than python. Can Python 3.0 be made faster than these two without any usage of modules/inlines/extensions?
Some tests show that even using pypy/psycho doesn’t beat Java 6.
I don’t want any responses/reasons explaining why python(context) is slow. Simply, I want to ask why can’t we look at this aspect urgently? Speed, Speed and Speed of execution is also important along with production speed (of-course!)
Appearance
Can we have private, protected stuff in classes rather than underscores which look dirty?? ( By the way I am happy with ‘self’)?
I am just wishing that these features be considered so that can I can boast more of my favorite language - Python.
Cheers, Don’t-Repeat-Yourself
I agree with J Ricketts: this is one of the best written articles I have ever read on the “WWW” and most anywhere else.
Rory — Normally, len(x) just delegates to x.len(), which can indeed be called directly. Did I misunderstand your objection?
rather x.len()
Nobody move- or the monkey gets it.
GREAT post.
Really amazing article and huge list of comments, now I am provoked by this and will definitely take up Python as I am beginner in it now, Thanks James and thanks Swaroop who directed me towards this article by his Book ‘A Byte Of Python’ :)