fbpx
dirtSimple.orgwhat stands in the way, becomes the way
Python Is Not Java

Python Is Not Java

I was recently looking at the source of a wxPython-based GUI application, about 45.5KLOC in size, not counting the libraries used (e.g. Twisted). The code was written by Java developers who are relatively new to Python, and it suffers from some performance issues (like a 30-second startup time). In examining the code, I found that they had done lots of things that make sense in Java, but which suck terribly in Python. Not because “Python is slower than Java”, but because there are easier ways to accomplish the same goals in Python, that wouldn’t even be possible in Java.

So, the sad thing is that these poor folks worked much, much harder than they needed to, in order to produce much more code than they needed to write, that then performs much more slowly than the equivalent idiomatic Python would. Some examples:

  • A static method in Java does not translate to a Python classmethod. Oh sure, it results in more or less the same effect, but the goal of a classmethod is actually to do something that’s usually not even possible in Java (like inheriting a non-default constructor). The idiomatic translation of a Java static method is usually a module-level function, not a classmethod or staticmethod. (And static final fields should translate to module-level constants.)

    This isn’t much of a performance issue, but a Python programmer who has to work with Java-idiom code like this will be rather irritated by typing Foo.Foo.someMethod when it should just be Foo.someFunction. But do note that calling a classmethod involves an additional memory allocation that calling a staticmethod or function does not.

    Oh, and all those Foo.Bar.Baz attribute chains don’t come for free, either. In Java, those dotted names are looked up by the compiler, so at runtime it really doesn’t matter how many of them you have. In Python, the lookups occur at runtime, so each dot counts. (Remember that in Python, “Flat is better than nested”, although it’s more related to “Readability counts” and “Simple is better than complex,” than to being about performance.)

  • Got a switch statement? The Python translation is a hash table, not a bunch of if-then statments. Got a bunch of if-then’s that wouldn’t be a switch statement in Java because strings are involved? It’s still a hash table. The CPython dictionary implementation uses one of the most highly-tuned hashtable implementations in the known universe. No code that you write yourself is going to work better, unless you’re the genetically-enhanced love child of Guido, Tim Peters, and Raymond Hettinger.

  • XML is not the answer. It is not even the question. To paraphrase Jamie Zawinski on regular expressions, “Some people, when confronted with a problem, think “I know, I’ll use XML.” Now they have two problems.”

    This is a different situation than in Java, because compared to Java code, XML is agile and flexible. Compared to Python code, XML is a boat anchor, a ball and chain. In Python, XML is something you use for interoperability, not your core functionality, because you simply don’t need it for that. In Java, XML can be your savior because it lets you implement domain-specific languages and increase the flexibility of your application “without coding”. In Java, avoiding coding is an advantage because coding means recompiling. But in Python, more often than not, code is easier to write than XML. And Python can process code much, much faster than your code can process XML. (Not only that, but you have to write the XML processing code, whereas Python itself is already written for you.)

    If you are a Java programmer, do not trust your instincts regarding whether you should use XML as part of your core application in Python. If you’re not implementing an existing XML standard for interoperability reasons, creating some kind of import/export format, or creating some kind of XML editor or processing tool, then Just Don’t Do It. At all. Ever. Not even just this once. Don’t even think about it. Drop that schema and put your hands in the air, now! If your application or platform will be used by Python developers, they will only thank you for not adding the burden of using XML to their workload.

    (The only exception to this is if your target audience really really needs XML for some strange reason. Like, they refuse to learn Python and will only pay you if you use XML, or if you plan to give them a nice GUI for editing the XML, and the GUI in question is something that somebody else wrote for editing XML and you get to use it for free. There are also other, very rare, architectural reasons to need XML. Trust me, they don’t apply to your app. If in doubt, explain your use case for XML to an experienced Python developer. Or, if you have a thick skin and don’t mind being laughed at, try explaining to a Lisp programmer why your application needs XML!)

  • Getters and setters are evil. Evil, evil, I say! Python objects are not Java beans. Do not write getters and setters. This is what the ‘property’ built-in is for. And do not take that to mean that you should write getters and setters, and then wrap them in ‘property’. That means that until you prove that you need anything more than a simple attribute access, don’t write getters and setters. They are a waste of CPU time, but more important, they are a waste of programmer time. Not just for the people writing the code and tests, but for the people who have to read and understand them as well.

    In Java, you have to use getters and setters because using public fields gives you no opportunity to go back and change your mind later to using getters and setters. So in Java, you might as well get the chore out of the way up front. In Python, this is silly, because you can start with a normal attribute and change your mind at any time, without affecting any clients of the class. So, don’t write getters and setters.

  • Code duplication is quite often a necessary evil in Java, where you must often write the same method over and over with minor variations (usually because of static typing constraints). It is not necessary or desirable to do this in Python (except in certain rare cases of inlining a few performance-critical functions). If you find yourself writing the same function over and over again with minor variations, it’s time to learn about closures. They’re really not that scary.

    Here’s what you do. You write a function that contains a function. The inner function is a template for the functions that you’re writing over and over again, but with variables in it for all the things that vary from one case of the function to the next. The outer function takes parameters that have the same names as those variables, and returns the inner function. Then, every place where you’d otherwise be writing yet another function, simply call the outer function, and assign the return value to the name you want the “duplicated” function to appear. Now, if you need to change how the pattern works, you only have to change it in one place: the template.

    In the application/platform I looked at, just one highly trivial application of this technique could have cut out hundreds of lines of deadweight code. Actually, since the particular boilerplate has to be used by developers developing plugins for the platform, it will save many, many more hundreds of lines of third-party developer code, while simplifying what those developers have to learn.

This is only the tip of the iceberg for Java->Python mindset migration, and about all I can get into right now without delving into an application’s specifics. Essentially, if you’ve been using Java for a while and are new to Python, do not trust your instincts. Your instincts are tuned to Java, not Python. Take a step back, and above all, stop writing so much code.

To do this, become more demanding of Python. Pretend that Python is a magic wand that will miraculously do whatever you want without you needing to lifting a finger. Ask, “how does Python already solve my problem?” and “What Python language feature most resembles my problem?” You will be absolutely astonished at how often it happens that thing you need is already there in some form. In fact, this phenomenon is so common, even among experienced Python programmers, that the Python community has a name for it. We call it “Guido’s time machine”, because sometimes it seems as though that’s the only way he could’ve known what we needed, before we knew it ourselves.

So, if you don’t feel like you’re at least ten times more productive with Python than Java, chances are good that you’ve been forgetting to use the time machine! (And if you miss your Java IDE, consider the possibility that it’s because your Python program is much more complex than it needs to be.)

The comment thread is now closed; it was beginning to degenerate into offtopic Python versus Java arguments.

Join the discussion
42 comments
  • Thank you very much! Your post resonates with me a great deal. I switched from Java to Python a while back, but I don’t have a CS background, so I’d like to request some clarification.

    First, when you say “hash table”, in Python I think dictionary. Is that correct? If so, does that mean you would create a dict that has the case value as the key and the appropriate callable as the item? How would you organize your code? Could you point me towards an example in, say, PEAK somewhere?

    Second question, regarding closures, the concept seems straight-forward, but could you again point me at an example in working code?

    Again, thank you for this post.

  • While I see most of the points, the “swith->hash-table” conversion is a bit confusing. Are you suggesting that for each option that would have originally been the “body” of the case statement, I should write a function, store it in a dict (w/ the key as the case value), and then look that up? Seems to loose some of the information attached w/ the switch…

  • Very interesting. As a Python programmer (mostly, over the last couple of years) who’s just returning to Java, I find some of the same points applying in reverse. But what’s much more frustrating is the drop in language level; so much of what’s done for you in Python needs to be put together painfully and explicitly in Java. And don’t get me started on static typing…

    ben
    http://www.benlast.com/

  • When does part 2 come out?!! Another problem I had was trying to figure out how to do reflection in Python, comming from writing reflection in Java. Also it would be good to have a section on dynamic code generation and evaluation. Dynamic code evalutaion in Python is an extremly powerful tool!

    Thanks,
    LHJ

  • Yes, hash table == dictionary. For simple examples, check out the “pickle” and “copy” modules in the Python standard library, which look up types in a dictionary to get the functions they need. A more sophisticated example is generic functions, about which I’ve posted several blog items here recently.

    Regarding closure examples, most of the ones I can think of in PEAK are a lot more complex than the simple form I described here, so I’ll make up a silly example. Suppose you are making lots of functions like:

    def addOne(x): return x+1
    def addTwo(x): return x+2

    then you can make something like:

    def makeAdder(addend):
    … def add_it(x): return x+addend
    … return add_it

    and use it like this:

    addOne = makeAdder(1)
    addTwo = makeAdder(2)

    Which is roughly equivalent to the original definitions of addOne and addTwo.

    As for losing context in converting a switch to a hash table, I would say, yes, you can lose context, but usually there’s a simple way to structure things so that it’s not too bad. However, I’ve also seen lots of code where switch-like blocks do nothing more than select another constant value to return, or each item is another function call anyway.

    I probably should have qualified this point more, or at least pointed out that there are other good reasons to use a dictionary when you’re making choices between behaviors, such as the fact that third parties can potentially add items to a dictionary, but they can’t add more branches to your if-then blocks. This is more of an issue for platforms and frameworks than for applications, of course.

  • I think first-class functions can save a lot of time, without being quite as sophisticated as closures. Their use is certainly a common Python idiom, and not present in Java (AFAIK).

    A typical example might be some pipelined code, where a function produces output. Say it sorts between “good” and “bad”. You don’t want it to simply return two lists, because you have (or want) to act on its results immediately.

    You could create objects and interfaces and whatnot (for a Java feel), but functions will do. The signature looks like “sort_virtue(input, good_func, bad_func)”; it calls “good_func(item)” when it encounters a good item, or “bad_func(item)” when it gets a bad one.

    When you are starting out, maybe you are lazy and just want to collect them. You make a list “good” and “bad”. You pass in “good.append” for good_func, and “bad.append” for bad_func. Later on you can refine, if you need to. If you need lots of state and whatnot, you can create a class with a “__call__” method. You’ve lost little future flexibility, but you’ve saved a lot of time — no new classes, no new interfaces, no new abstractions, and short documentation.

    There’s lots of other similar use cases where passing functions around is fast and powerful. It’s a good first step on your way to closures, and it certainly has to be mastered first.

  • Wonderful !
    It’s not the first time I read from you but this time I add your name on my small personnal python-gurus-must-read list : Those people with high-level thoughts yet understandable by me. Reading your prose give me the delightful feeling to be intelligent 🙂

  • re:”””What advice do you have for translating multithreaded Java applications? Does Python have any nice concurrency semantics that transcend Threads?”””

    There aren’t very many good reasons to use pre-emptive threads, in any language. Co-operative multitasking is far less prone to non-reproducible heisenbugs.

    In the case of Python, there are many asynchronous toolkits (e.g. Twisted, peak.events, and Medusa) designed to make it easier to do co-operative multitasking in Python. There’s also Stackless Python, an alternative CPython implementation which builds ultra-lightweight co-operative threads into the language and libraries. And, last but not least, there’s the Greenlets library which can work with regular CPython to give you Stackless-like task switching.

    re:”””Another problem I had was trying to figure out how to do reflection in Python, comming from writing reflection in Java. Also it would be good to have a section on dynamic code generation and evaluation.”””

    Well, in Python you don’t have to use .class to go from the name of a class to having an object you can reflect on, because in Python, classes are already an object. The ‘dir()’ function gives you a list of a class’ attribute names. The ‘inspect’ module lets you examine function signatures. The ‘new’ module lets you create new “classic” classes, modules, functions, and code objects.

    You can create new-style classes them with the ‘type()’ callable: ‘type(name,bases_tuple,classdict)’ returns a new class with the given names, bases, and class dictionary (containing non-inherited class attributes and methods).

    Using the ‘new’ module, you can create code objects from a bytecode string, much like you can create a class from bytecode in Java. But, it’s usually easier to use the ‘compile’ builtin to compile a string with your desired source code. Or, use the ‘exec’ statement to execute some source code.

    I’m not going into a lot of detail here, but it’s hard to talk about these things without specific use cases. Mostly, my article was about some of the issues I encountered in one specific application. The only reflection/code-generation issue it had was using ‘getattr()’ unnecessarily; i.e. with constant strings.

    I suspect this is because in the same situation in Java you would have had to use the reflection API to do what it was doing. In Python, it suffices to say ‘classvar.foo’, where in Java you’d need to call some kind of field introspection method on ‘classvar’ if it was an instance of java.lang.Class (or whatever the type I’m thinking of is.)

  • Please…

    Just because some people aren’t experts in one language or another doesn’t mean one language is better than the other.

    Anyone whos coded/ported in multiple languages knows that you do things differently in each. Each has its own strengths and weaknesses. Its also why its hard to be an export on any one language.

    I’ve been working with ada code. We have 3 types.
    Straight ada- Written from ground up. Is easy to read simple and powerfull.

    adatran – Ada ported staight from fortran. Ugly.
    adac – Ada ported from C. Ugly hard.

    The original code always makes good sense for the language it was written in. Stop worrying about lines of code, length of variable names etc.. Is the code readable maintainable is a much more important.

  • This blog article was pure genius!

    I often have to switch between the java and the python style. Sometimes in the process idioms get mixed in my mind and I suffer more than necessary. Having it written out instead of just trusting intuition while doing makes the issue clearer and decisions easier. Somebody should put up a website with rules of thumb to convert java to python and the reverse (python->java).

  • Another point I’m tempted to add is: consider monkey-patching before subclassing. Suppose you are using a standard library and the standard library doesn’t have all the functionality, it is possible to replace the code or add more calls to the original class. This can speed up prototyping, since you get to experiment without subclassing.

  • re:”””Just because some people aren’t experts in one language or another doesn’t mean one language is better than the other.”””

    Of course not. We all know that Python is the better language, anyway. 😉

    More seriously, I would say that “better” isn’t very specific as to what criterion is being used for judgment. Criteria like “more powerful” are much more easily measured. For example, it’s trivial to illustrate numerous ways in which Python is a more powerful language than Java — and of course I already did that.

    But “more powerful” doesn’t necessarily translate to “better”, since Lisp is “more powerful” than Python in an objective sense, but you probably won’t catch me writing Lisp code any time soon. (In fact my last Lisp usage was probably writing Emacs macros, back about a decade ago.)

    re:Python/Java phrasebooks

    See PythonForJavaProgrammers, for a wiki where you can perhaps add your own ideas.

    re:monkeypatching

    I consider monkeypatching a strategy of last-resort, because it doesn’t scale. If other modules monkeypatch the same thing, now where are you? I believe the long-term replacement for monkeypatching is built-in support for generic functions, which allow third parties to cleanly add additional processing cases to an existing function.

  • I feel your pain. In particular I have to second your statements about XML (the other commenters neglected their duties here:-). Yeah, XML… While traditional compiler tools remained obscure and idiosyncratic despite of man-centuries of R&D, XML finally brought language engineering
    to the masses. Never was creating your own domain-specific language and getting a parser for it so easy! (Although habitual grumblers will argue that all these XML-based languages look the same and can neither be read nor written by humans with any residual self esteem…) But what _really_ tends to be forgotten in all this glory is the fact that language implementation does not end at parsing. You can parse? Fine, now get ready for real thing: implement your language’s semantics! We wish you good luck not only in reinventing all the standard wheels of control flow and data structures (add a modern type system in your copious free time), but also in getting your implementation as mature and trusted as the one of
    any established programming language, especially the OSS ones. Your language does not need any bells and whistles? It will, two years from now (given you still have users they’ll demand them ever more loudly), or your language will be dead and forgotten. Don’t forget to add good error handling and make your implementation interoperable with at least those parts of the rest of the world essential to your application domain.

    Unconvinced readers might have a look at the evolution of Ant, the Java build tool. The Ant spec language started as a saner, XML-based version of make (no more tab-induced trouble) and now approaches the complexity of a full-blown scripting language – XML-based, unreadable, and not reusing a single line of code from all the mature scripting language implementations out there. Ant users and devlopers eventually figured out ways to save the hassle and just import Jython or Groovy scripts instead recently.
    In a blog entry that seems to have expired meanwhile, James Duncan Davidson explained that he would base Ant on a real, established language like Jython would he design it again. There’s still a link left at http://fishbowl.pastiche.org/2003/05/05/dear_xml_programmers
    which page in its entirety grinds the same axe.

    I also liked your reference-in-passing about the Lispers’ special relationship towards XML. Erik Naggum’s XML-related rants on comp.lang.lisp are real classics (independent from other aspects of his personality as apparent from his postings). Take this for an appetizer: “Structure is _nothing_ if it is all you got. Skeletons _spook_ people if they try to walk around on their own. I really wonder why XML does not.”

  • As a single Pythonista in a sea of Java developers, I currently write both Java and Python code. However, I find that the best way to write Java code is to sketch it out in Python first then translate to Java. That way I get the structure and design right before I formalize. The success I’ve had with this approach leads me to believe that Python is to Java as C is to assembly code.

  • Hello,
    Can you show an example of when to many if thens should be turned into a hash lookup? Or can you provide a pointer to a good reference. I often have a lot of if elifs in my programs and I would like to make them easier to manage…

  • What are your if-then’s checking? Type? Value? Range? Strings? Integers? What do the various branches actually do? The appropriate mechanism for testing will differ accordingly.

    In other words, give *me* an example of one of your big conditional blocks, and I’ll suggest alternatives.

  • Another thing I notice with Java is the “Bundle it up in an object” attitude. In Python, sometimes one can work quite effectively without putting _everything_ in objects.

    For example, I frequently find it useful to mix functional-style code (written using functions that return the results of list comprehensions) with more conventional procedural OO code. Forcing myself to pick either one model or the other would cost me time, and result in buggier, less readable code.

    As someone who _loathed_ functional programming when first exposed to it, I’ve found it’s grown on me a lot. Not being forced to use purely functional methods for problems that were poorly suited to a functional approach helps. The freedom Python gives me to choose a basic procedural, OO, or functional approach as the problem warrants is the main reason I’m finding I like it so much, though.

    If you do get into functional-style Python, please keep one thing in mind. Nesting list comprehensions is rarely cool – it’s usually much more readable and maintanable to split the inner comprehension into a new function.

    Can’t-wait-for-generator-expressions ‘ly yours 😉

    Craig Ringer

  • I’m not sure why people are asking for dict-as-switch examples, but here are some cases. If you are using the if-elif-else to set some variables put all the data up front in a hash. Here is an example for a text object that can take a point size (int) or a name as the ‘size’ argument.
    size_to_point = {‘small’:7, ‘normal’:9, ‘large’:12,}
    try:
    point_size = size_to_point[size]
    except KeyError: # must be an int
    point_size = size

    If the if-elif-else is doing different operations on the data make a function lookup table like you would in C.

    color_ops = {‘blur’:imageops.blur, ‘dodge’: mydodge,}

    You can mix these two together by making the value of the dictionary a tuple. In the data case this can be handy for setting more than one variable.

    (color, size, font) = font_desc[font_name]

    The formatting on that sucks, but I already typed it all in and blogger doesn’t tell me what tags are allowed.

  • There is a nicer way to do the transform:

    size_to_point = {‘small’:7, ‘normal’:9, ‘large’:12,0:9}
    point_size = size_to_point.get(size,size)

    dict.get is always a win over using try/except (note that I added a case for passing in 0 too.)

  • What makes you think this code would be acceptable in Java? It’s *not* okay on the teams I work on to write a bunch of duplicate code just because you’re using Java. This is not just a Python thing, it’s a writing code well thing. Anonymous classes can do much the same thing as closures, and well-written Java code is easier to read than XML.

    Also, I think you left out the most important tip: If your team’s programmers are more comfortable in Java, *stick to Java*. Python has some nice language features, but by switching you’re giving up a lot too.

  • In Java, alas, the cure for duplicated code can be worse than the disease. For example, you replace duplication of the code with duplication of code to create and call the pseudo-closure.

    Not only that, but there are so many places where lots and lots of typing is required in Java, to the extent that one becomes numbed to seeing large masses of similar code. The problem is that Java developers don’t *see* that this code is duplicative, because it’s stuff that there’s no practical way in Java to NOT duplicate.

    However, that same code, translated to Python, will often immediately suggest ways to restructure for less duplication. For example, the existence of keyword arguments and default values in Python makes it possible to put even complex alternate behaviors into a single function. The corresponding solution in Java involves lots of little methods that call each other or duplicate pieces of the behavior, assuming you think to do it in the first place.

    Anyway, the kind of duplication I was talking about in the post was duplication that’s systemic and idiomatic to Java as a language, because it’s not practical to remove the duplication due to language limitations. I wasn’t talking about your everyday non-DRY sorts of code duplication.

  • Ok, I understand the first paragraph, and I can accept that your list of tips is valid and reasonable, but try as I might, I can’t make the leap from A to B — it would be helpful if you could illustrate these paradigm errors directly with examples from the wxPython code so we can see directly how each applies, and observe the difference in performance once the code is fixed.

  • I’d want to get permission from the authors of that code before I did that. In any case, the biggest performance boost would be in getting rid of the XML processing, which is directly responsible for at least half of its startup time. But that’s not a quick one-line change, and there’s no way the patch would fit in a comment here.

    One of the other major performance drains in the app is actually its use of a __getattr__ hook, instead of using descriptors. That too is a significant refactoring. About the only refactoring pattern that would easily fit here would be the duplicated code thing, which I’ve already illustrated here in a previous comment.

  • The remarks concerning XML seem to address a quite small slot of XMLs scope only and I’m not even sure, which slot. At least the hint to use Python instead points vaguely into “active content” direction.
    As a data exchange format between different languages or for a data store prepared for applications not yet written I see no easy substitution (by a pickled instance or something similar).

  • “””The remarks concerning XML seem to address a quite small slot of XMLs scope only and I’m not even sure, which slot.”””

    Does this clear it up:

    “If you’re not implementing an existing XML standard for interoperability reasons, creating some kind of import/export format, or creating some kind of XML editor or processing tool, then Just Don’t Do It.”

    These “slots” as you call them, are the main places where implementing an XML-based format is sensible. There are other times and places where an XML format is also useful, but they’re fairly uncommon. Mainly, they amount to places where you actually need some kind of *markup*, as opposed to just a data format.

    “””As a data exchange format between different languages”””

    i.e., an “import/export format”

    “””or for a data store prepared for applications not yet written”””

    You’ll have a lot better chance at decent performance and usability with a relational database. Unless you’re talking about a way to specify data to go into the database, in which case we’re back to import/export format.

  • Hi Philip,

    this post is cool, but why Python? You are talking about simplicity, but have you ever tried to code in Ruby?

    Szymon Drejewicz

    P.S. For example, in Ruby tinyp2p takes 6 lines of code, not 15 🙂 Most of expressions in Ruby is much cleaner than in Python, believe me.

  • One thing that struck me (as a Java developer) is that I found the comments about XML to be very applicable to Java development. I too have seen the pain that results from developers saying, “We’ll use XML! It’ll be easy!”

    Can someone elaborate on the differences, or is this an example where we actually share the pain?

  • I develop applications in both Python and Java. The Java way of doing things makes you jump though hoops to do simple things. Python’s approach is much more streamlined and intuitive for most operations.

    Java is also screwy in nature since the designers, in their infinite wisdom said “operator overloading is bad” and then they created the String class which overloads the “+” operator! Wait a second, why can’t I overload the “+” operator in my Java classes? If String can do it, why can’t MyString or MyOtherClass overload operators?

    Then they created crippled classes that wrap primitive types like Integer, Long, etc… Yet these classes have no useful methods, heck, you can’t even change their value once you create them. A true Integer class would have allowed you to “add”, “subtract”, etc.. but not in Java. You need to do so at the primitive level yet you need the Integer objects if you want to use them in a hashtable, list, etc..

    Java:
    // store and retrieve an integer in a list
    List l = new ArrayList();
    l.add ( new Integer(123) );
    int i = l.get(0).intValue();

    Python:
    # store and retieve an integer in a list
    l = [123]
    i = l[0]

    Java forces you to write classes to do anything yet they provide useless Integer classes. That is, say you want to output “Hello World” then you need to create a class and a method that does so. That’s the thing, “not everything *is* an object” so why does everything need to be a class? Obviously, the primitives aren’t objects so why can’t I write functions that aren’t member functions? Other OOP languages don’t force you to do everything at the object level (eg. C++, Python, etc).

    Common operations in most languages are to coerce (or cast) values from one type to another. For instance, you have a string “1234” but want the value as an integer, so what do you do…

    Java: int i = Integer.parseInt(“1234”);
    Python: i = int(“1234”)

    Also, the reverse, you have an integer 9876 and you want it as a string:

    Java: String s = “”+9876;
    -or-
    Java: String s = String.valueOf(9876);
    Python: s = str(9876);

    So you want to compare 2 strings for equality?

    Java:
    String s1 = “string 1”;
    String s2 = “string 2”;
    if (s1.equals(s2)) { // do something }

    Python:
    s1 = “string 1”
    s2 = “string 2”
    if s1 == s2: # do something

    Why did the java designers overload ‘+’ but not equality? How often do you really want to compare the identity of two strings rather than the value of them?

    Ahhh, in just a few examples, I’ve demonstrated how much more elegant Python is than Java… You want to overload operators you can. You want to add two integer objects, you can. You want to output “Hello World” you can do so in a class, in a function or inline. It’s your choice.

    That’s the thing about coding Python, it’s your choice. Why let the language designers box you into a corner as you jump through hoops to do simple things. If you have to do so for the simple things just imagine what death defying acts you’ll need to perform in order to do complex things!

  • Python Rocks >
    Actually, you should not convert an integer to a string through the str() construct, it’s horribly ineficient.

    Replacing “s = str(9876)” with “s = `9876`” shows a noticeable increase in efficiency: on my box, 10000000 runs of the conversion operation (“str(9876)” or “`9876`”) yields 12.26 seconds for the first construct, and 7.35 for the second one, 40% faster.

    And I find it much more readable to boot

  • It’s even worse:

    // store and retrieve an integer in a list
    List l = new ArrayList();
    l.add ( new Integer(123) );
    int i = l.((Integer) get(0)).intValue();

    The get() method returns Object, not Integer, so you need to downcast it before you can call intValue. Eyew.

  • Just wanted to make a reply to the person who was talking about ANT. While I agree that XML wasn’t necessarily the greatest language in the world to use to describe the processes in ANT. The reason ANT is so popular is because it has an incredibly powerful set of libraries that make it trivial to do very complex operations (especially file operations). I wrote a cron-like application that handles hundreds of tasks a day using Ant as a core and it saved me vast amounts of time.

    It also integrates very well with IDE’s, tools, and other such fun uses. This is probably Java’s greatest strength. As a language its pretty poor (mainly because Sun’s philosophy seems to be anything that could have been done correct on the first try should instead be hacked together and fixed later), but there are so many libraries and tools to do useful things in java.

    I’m actually about to switch to using python from java, but I’m definitely going to miss things like Ant (which I may end up trying to use anyway) and Intellij Idea. Are there good programming tools like these available in Python? Which ones should I use?

  • tammo, try this…

    int l[] = new int[] { 1 };
    int i = l[0];

    But of course the only operation you get for free on a primitive array is length, so Python’s list is more useful.

dirtSimple.org

Menu

Stay In Touch

Follow our feeds or subscribe to get new articles by email on these topics:

  • RSS
  • RSS
  • RSS

Delivered by FeedBurner

Get Unstuck, FAST

Cover photo of "A Minute To Unlimit You" by PJ Eby
Skip to toolbar