On Thu, Apr 30, 2015 at 3:10 PM, Marko Rauhamaa <ma...@pacujo.net> wrote: > Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info>: > >> If you have a Java background, you might find this useful: >> >> http://dirtsimple.org/2004/12/python-is-not-java.html >> >> http://dirtsimple.org/2004/12/java-is-not-python-either.html > > Unfortunately, I didn't find those articles all that insightful. > > The one big difference between Java and Python is interfaces vs > ducktyping. In Java, you do everything through formal interfaces. In > Python, you do nothing through formal interfaces.
The other big difference between C++/Java and Python is that the former have everything hidden by default, and the latter has everything public by default. Compare: class Point { int x, y; public: Point(int _x, int _y): x(_x), y(_y) {} int get_x() {return x;} void set_x(int newx) {x = newx;} int get_y() {return y;} void set_y(int newy) {x = newy;} }; void interpolate_points(Point from, Point to, Point **target, int count) { int delta_x = to.get_x() - from.get_x(); int delta_y = to.get_y() - from.get_y(); for (int i=0;i<count;++i) target[i] = new Point(from.get_x() + delta_x*i/count, from.get_y() + delta_y*i/count); } class Point(object): def __init__(self, x, y): self.x = x self.y = y def interpolate_points(from, to, count): delta_x = to.x - from.x delta_y = to.y - from.y return [Point(from.x + delta_y*i/count, from.y + delta_y*i/count) for i in range(count)] Okay, part of the improvement is the list comp rather than C-style array return, and you could improve on that some in C++ even; but the rigmarole of getters and setters is a completely unnecessary bug magnet. (There's one in the above code. I was going to fix it, but it's more indicative to leave it there.) Most classes do not need that overhead. In the rare cases where they do, Python lets you smoothly shift from a simple member to a property, so you can add logging or whatever. (Though... don't abuse that. I've seen code that puts @property on functions that do *network operations*, I kid you not. This completely violates the expectation that attribute lookup is simple and cheap.) As a small side benefit, there's no hassles about naming ("get_x" vs "_x" vs "x"); you could avoid _x by using a Python-style "this->x" everywhere in the C++ code, but that won't fix get_x. So clearly Python has the advantage, right? Well, not so clear. The philosophical abhorrence of remote mutation in C++ makes it a lot easier to reason about the code - you can look at the class definition itself and guarantee you can see every change to a private member. (Aside from naughty pointer manipulation and stuff. But in Python, we have to say "Aside from fiddling with ctypes", so this is like the Mistform Ultimus disclaimer[1].) In Python, you have to balance that in application code; is it safe to change some object's member? Can you just reach in and change the "read_callback" member to be a new function reference, or might it have been referenced somewhere else? Will you cause problems for yourself by replacing this actual file with a StringIO file-like object? How can you know? So the freedom is there, but it has to be used intelligently. ChrisA [1] eg http://archive.wizards.com/Magic/Magazine/Article.aspx?x=mtg/daily/arcana/1370 and http://archive.wizards.com/Magic/magazine/article.aspx?x=mtg/daily/arcana/1300 -- https://mail.python.org/mailman/listinfo/python-list