What’s New In Python 3.4
docs.python.org
docs.python.org
http://www.python.org/dev/peps/pep-0443/
What's going on here is that Python has added support for another kind of polymorphism known as "single dispatch".
This allows you to write a function with several implementations, each associated with one or more types of input arguments. The "dispatcher" (called 'singledispatch' and implemented as a Python function decorator) figures out which implementation to choose based on the type of the argument. It also maintains a registry of types -> function implementations.
This is not technically "multimethods" -- which can also be implemented as a decorator, as GvR did in 2005[1] -- but it's related[2].
Also, the other interesting thing about this change is that the library is already on Bitbucket[3] and PyPI[4] and has been tested to work as a backport with Python 2.6+. So you can start using this today, even if you're not on 3.x!
[1] http://www.artima.com/weblogs/viewpost.jsp?thread=101605
[2] http://en.wikipedia.org/wiki/Dynamic_dispatch
Is this method overloading or am I missing something?
http://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch...
Double dispatch is generally simulated with imperative languages via the Visitor Pattern. Generally used when you have objects that won't change their structure very much (and are backed by an interface of some sort [also needed for the polymorphism aspect of the pattern]), but have to do lots of various manipulations with them. That way, you don't have to change the interface each time you add another method. Also referred to as "inversion of control." I used it before for filesystem type objects and for walking over the structure of an XML file (though both times were for school related projects). I could probably dig up the labs and post them on my Github for anyone interested. It's pretty cool how it works (and sort of hard to wrap one's head around initially), but not something I would consider using often.
Scala has a unique take on double dispatch[1][2] for being a hybrid imperative/functional language.
[1] http://stackoverflow.com/questions/8618082/visitor-pattern-i...
[2] http://blog.nirav.name/2009/04/how-scalas-pattern-matching-c...
Single dispatch is pretty standard polymorphism, C++ can do that.
What this module adds is "functional single dispatch".
So, whereas before you'd always be forced to implement some type-varying function using two classes `HandleA` and `HandleB`, each with an implementation for `handle`:
class HandleA:
def handle(self):
pass
class HandleB:
def handle(self):
pass
def main(obj):
# obj could be instance of HandleA or HandleB
obj.handle()
In this case, "dynamic dispatch" is done by `obj.handle()`, which will pick a different implementation depending on the type of obj.With this PEP/stdlib addition, you can now write two functions, `handle_A` and `handle_B`, which take an argument, `obj`, and are dynamically dispatched using the generic function `handle`.
from functools import singledispatch
@singledispatch
def handle(obj):
pass
@handle.register(A)
def handle_A(obj):
pass
@handle.register(B)
def handle_B(obj):
pass
def main(obj):
# obj could be instance of A or B
handle(obj)
And in this case, "dynamic dispatch" is done by `handle(obj)`, or really, by the dispatcher decorator. It chooses `handle_A` or `handle_B` based on the type of the `obj` argumentThe reason this is a nice addition is because it makes Python eminently "multi-paradigm" -- you can choose object-oriented or functional styles depending on your taste and the applicability to the task at hand, instead of being forced into one programming style or the other.
(the content of my comments got long enough that I decided to document them for posterity over on my blog: http://www.pixelmonkey.org/2013/10/20/singledispatch)
I don't really understand the benefit of mm and dispatch. This sounds useful for building routes in webapp. But for library, it sounds like we are bringing back C++'s single interface, multiple types... I don't even remember what that is called.
"Text is always Unicode. Read it in as UTF-8. Write it out as UTF-8. Everything in between just works."
This was not true up through 3.2, because Unicode in Python <= 3.2 was an abstraction that leaked some very unfortunate implementation details. There was the chance that you were on a "narrow build" of Python, where Unicode characters in memory were fixed to be two bytes long, so you couldn't perform most operations on characters outside the Basic Multilingual Plane. You could kind of fake it sometimes, but it meant you had to be thinking about "okay, how is this text really represented in memory" all the time, and explicitly coding around the fact that two different installations of Python with the same version number have different behavior.
Python 3.3 switched to a flexible string representation that eliminated the need for narrow and wide builds. However, operations in this representation weren't tested well enough for non-BMP characters, so running something like text.lower() on arbitrary text could now give you a SystemError (http://bugs.python.org/issue18183).
With that bug fixed in Python 3.4, that removes the last thing I know of standing in the way of Unicode just working.
[0] http://nedbatchelder.com/text/unipain.html [1] http://nedbatchelder.com/text/unipain/unipain.html#35
This is great for those maintaining substantial codebases in the language, though.
The thorough specification process gives lots of warning for the introduction of changes (so you can almost update on release day if you were really so inclined and prepared).
Edit: Though on a re-read, clear, comprehensive newbie friendly documentation is something that (somewhat unrelatedly) Python does have. My bad.
Thanks! Now I don't have to do this on every box anymore for using Python.
import readline
import rlcompleter
readline.parse_and_bind('tab: complete') import readline
import rlcompleter
if 'libedit' in readline.__doc__:
readline.parse_and_bind("bind ^I rl_complete")
else:
readline.parse_and_bind("tab: complete")
[1] http://stackoverflow.com/a/7116997/10583After finding bpython this is a bit underwhelming. Perhaps they should just include it by default.
But, ever since I found out about algebraic data types from other languages, I keep wanting those. There's not quite a good way to do those in Python. (I've used both "tuple subclass" and "__slots__," but both of those have their own little quirks.)
> if MyType.ConstructorA(a):
> ...
> elif MyType.ConstructorB(a):
> ...
or even something like
> with MyType.ConstructorA(a) as b, c:
> ...
> else with MyType.ConstructB(a) as d:
> ...
a "with/else with" construct would be a fairly straightforward addition to Python's "context manager" interface.
" This PEP removes the current limitations and quirks of object finalization. With it, objects with __del__() methods, as well as generators with finally clauses, can be finalized when they are part of a reference cycle. "
This has been a notorious limitation in Python forever, and in 3.4 it's finally solved.
Is there anyone else who is still procrastinating moving their workflow to Python3?
Are there any major libraries that have not yet been ported to Python 3? I'd be interested to hear about others' experiences making the plunge.
boto, fabric, Django (still 'experimental'), and various django packages are my blockers.
gevent also doesn't support python 3.x yet afaik. Can the asyncio stuff supercede it?
There go half of my bugs. ;-)
On the bright side since django 1.5 has been released with python 3 support, many related projects have moved to python3. Still not completely there yet, but moving forward.
Shameless plug: I've been testing little badges to tell which requirements are python 3 ready or not on requires.io (https://requires.io). Should be in production later today or tomorrow.
An example of project that could consider making the jump from Python2 to Python3: https://requires.io/github/canassa/sodexo-api/requirements/?...
Python3 ended up being the target for server-side bits. Thanks to the fact that Pyramid now is Python3 capable.
We are still finding Python3 issues. Deploying Python3 on RHEL was a bit of a pain, most solved by RH Software Collections providing a python3.3 build, and the functioning state of virtualenv+pip.
Not being able to use mod_wsgi with python3 was a bit of a pain, ( fastcgi wrapper, to the rescue ) but solved.
Debian Jessie will default to Python 3 only I heard. I am starting to only install python3-* packages.
I have recently switched my work to Python and just started development on what will become a series of web projects all done in Python + Django. Yes, when it comes to Python I am a noob.
Looking at it with fresh eyes it seems that the most useful ecosystem is solidly rooted in the 2.7.x branch. Books and online courses promote the idea of using 2.7.x. My kid enrolled in the MIT intro to CS edX course and they use 2.7.5. Codecademy, same thing.
From the perspective of developing a number of non-trivial web-based products, how should I view the 2.7.x and 3.x ecosystems? Do you see a timeline to a transition? How should one prepare for it (or not)? What should one avoid?
At the moment it seems safe to pretty much ignore 3.x. I kind of hate that because I have this intense desire to always work with the the latest stable release of any software I use. Here things are different due to the surrounding ecosystem of libraries and tools. I'd certainly appreciate any and all help in understanding this a bit better.
And, regarding kids, I'm teaching mine Python 3 only (no time wasted on Py 2) and the latest HTML5/CSS3 (no time wasted learning workarounds for obsolete browsers). I think they're better off focusing entirely on preparing for the future, not spending part of their time preparing for the past.
At this point I'll help him through this phase and perhaps then make 3.x part of the continuing learning experience. In other words, if you are going to be in CS you will always have to deal with shifts in technology, this being a perfect teaching moment for him to learn that.
OS/2
I don't think we'll ever move... well not in a next year or two.
I find the mainframe fascinating, honestly. It's an entirely different world than the one I'm used to, from terminology to how systems are structured.