I'm a java programmer, but now entering the "realm of python" for some stuff for which Python works better. I'm quite sure a good portion of my code would look weird for a Python programmer (e.g. using parenthesis on every if).
I know each language has its own conventions and set of "habits". So, from a readability standpoint what are conventions and practices which is "the way to go" in Java, but are not really the "pythonic way" to do stuff?
There's no simple answer to that question. It takes time for your code to be "Pythonic". Don't try and recreate Java idioms in Python. It will just take time to learn Python idioms.
Take a look at Code Like a Pythonista: Idiomatic Python, Style Guide for Python Code and Python for Java Programmers (archived).
Jacob Hallén once observed that the best Python style follows Tufte's rejection of decoration (though Tufte's field is not programming languages, but visual display of information): don't waste "ink" (pixels) or "paper" (space) for mere decoration.
A lot follows from this principle: no redundant parentheses, no semicolons, no silly "ascii boxes" in comments and docstrings, no wasted space to "align" things on different rows, single quotes unless you specifically need double quotes, no \ to continue lines except when mandatory, no comments that merely remind the reader of the language's rules (if the reader does not know the language you're in trouble anyway;-), and so forth.
I should point out that some of these consequences of the "Tufte spirit of Python" are more controversial than others, within the Python community. But the language sure respects "Tufte's Spirit" pretty well...
Moving to "more controversial" (but sanctioned by the Zen of Python -- import this at an interpreter prompt): "flat is better than nested", so "get out as soon as sensible" rather than nesting. Let me explain:
if foo:
return bar
else:
baz = fie(fum)
return baz + blab
this isn't terrible, but neither is it optimal: since "return" ``gets out'', you can save the nesting:
if foo:
return bar
baz = fie(fum)
return baz + blab
A sharper example:
for item in container:
if interesting(item):
dothis(item)
dothat(item)
theother(item)
that large block being double-nested is not neat... consider the flatter style:
for item in container:
if not interesting(item):
continue
dothis(item)
dothat(item)
theother(item)
BTW, and an aside that's not specifically of Python-exclusive style -- one of my pet peeves (in any language, but in Python Tufte's Spirit supports me;-):
if not something:
this()
that()
theother()
else:
blih()
bluh()
blah()
"if not ... else" is contorted! Swap the two halves and lose the not:
if something:
blih()
bluh()
blah()
else:
this()
that()
theother()
The best place to start is probably PEP-8, which is the official Python style guide. It covers a lot of the basics for what is considered standard.
In addition, some previous stackoverflow questions:
What are the important language features idioms of python to learn early on?
What does pythonic mean?
What defines “pythonian” or “pythonic”?
Python: Am I missing something?
Zen of python
"Everything is a class" is a Java idiom that's specifically not a Python idiom. (Almost) everything can be a class in Python, and if that's more comfortable for you then go for it, but Python doesn't require such a thing. Python is not a purely object-oriented language, and in my (limited) experience it's good to take that to heart.
Syntax is only the tip of an iceberg. There are a number of different language construct that Java programmers should be aware of, e.g. Python do not need to use interface
Creating an interface and swappable implementations in python - Stack Overflow
The other really useful idiom is everything can be convert to a boolean value with an intuitive meaning in Python. For example, to check for an empty array, you simply do
if not my_array:
return
...process my_array...
The first condition is equivalent to Java's
if ((my_array == null) || (my_array.length == 0)) {
return
}
This is a godsend in Python. Not only is it more concise, it also avoid a Java pitfall where many people do not check for both conditions consistently. Countless NullPointerException are averted as a result.
Related
Is there a practical or historical reasoning behind languages allowing the most egregious naming convention taboos? The two most obvious examples are uppercase function names and lowercase class names, which I often see violated in stackoverflow newbie questions.
There is no style-justification that I know of where you can do these things, so why are they even allowed to compile? At the moment, my theories are
It was not such a taboo when the language was built,
It would make some important edge cases impossible, or
It's not the language's job to enforce good style.
I can find nothing on this topic (some links are below).
There are some conventions, such as underscores beginning variable names, or Hungarian notation (the latter of which I have been personally disabused of in comments) that are not overwhelmingly accepted, but are less divisive.
I'm asking this as a Java programmer, but would also be interested in answers form other language's.
Some links:
http://en.wikipedia.org/wiki/Naming_convention_(programming)#Java
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
http://en.wikibooks.org/wiki/Java_Programming/History
How important are naming conventions for getters in Java?
Coding style is like writing style. If you write in a style that is diFFicult TO READ And does not read very well your mINd hAs GReat diFFICULTies actUally understanding what you are reading.
If, however, like in normal reading text - it is laid out in a form that matches well with what your mind expects then it is clear and easy to understand.
On the other hand, if the language actually FORCED you to write everything using EXACTLY the the right syntax then not only would it make coding slow and awkward but it would restrict your expressiveness.
Many years ago I came across a language that allowed you to add strange symbols to variable names. Users were allowed to do thing like:
var a=b = a = b;
var c<d = c > d;
if ( a=b & c<d ) ...
i.e. a=b was a perfectly acceptable variable name, so was c<d. As I am sure you would agree, this led to many mistakes of interpretation. Even if a new language allowed that I would not use it. Coding standards are for consistency and helping the human mind understand, syntax is for helping the computer mind understand.
Depending on the language designer's intent some languages are more opinionated than others when it comes to implementation and how the designers think things should be done.
The easiest example I can think of right now is Go, which has unit testing and code formatting built in. The designers are of the opinion that things should be done a certain way and they provide you the tools to do it.
Other languages do nothing of the sort like Scala where the language designers were very unopinionated in their implementation and supply you the tools to accomplish any given task in 10 different ways.
This isn't to say that some languages are built under tyrannical rule and others are extremely loose with their requirements. Its merely a choice made by the language designers which we end up having to live with.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Java operator overload
In c++, we can perform the operator overloading. But Java is also a Object oriented language. So why java doesn't support overloading?
http://java.sun.com/docs/white/langenv/Simple.doc2.html
There are no means provided by which
programmers can overload the standard
arithmetic operators. Once again, the
effects of operator overloading can be
just as easily achieved by declaring a
class, appropriate instance variables,
and appropriate methods to manipulate
those variables. Eliminating operator
overloading leads to great
simplification of code.
The last statement is of course very subjective.
Actually, it does support operator overloading... of a very limited, built-in only nature. For instance "+" is overloaded for String's in addition to the usual arithmetic.
Of course, most people want to know why Java does not support user-defined operator overloading. :-) The simplest answer seems to be that the Java creators did not, at the time, see any clean way to add it to the language without making Java a mess (like C++) in the process.
it's design goals to make java simpler than c++
We wanted to build a system that could
be programmed easily without a lot of
esoteric training and which leveraged
today’s standard practice. So even
though we found that C++ was
unsuitable, we designed Java as
closely to C++ as possible in order to
make the system more comprehensible.
Java omits many rarely used, poorly
understood, confusing features of C++
that, in our experience, bring more
grief than benefit.
from here:
The Java Language: An Overview
The code is harder to understand when you use operator overloading in c++. May be that was the reason why Java developers decided not to implement it.
Really the code rich with overloaded operators can be very misleading and hard to read, just like the code with a plenty of macros.
Note that there's an anomaly in that the 'plus' operator is overloaded for java.lang.String.
Way back when, the news was that the Java team looked at other languages (primarily C++) and tried to make a judgment call as to what language level features to include (or exclude) from Java.
Operator overloading was a big new feature in C++ and lots of budding programmers used it to solve problems in interesting ways. Unfortunately, most of those ways were buggy, and few programmers overloaded operators in ways that were "programmer portable". As a result, reading a program would often miss that "magic" code had been introduced in the "+" operator (or something else). Outside of numbers (vectors, etc.) you also had disagreements as to what "+" might mean.
So the cover story (no idea if it was true) was that the Java team saw that you could just name methods sum.plus(...) and it would be obvious that the call was to user written code (which could be overloaded) while the reserved operations "+", etc. would only did what the language defined. This would increase some types of code readability at the expense of a few extra words.
Is it true, or is it an attempt to back fill history with rationalizations? I don't know. Perhaps the language implementers just were busy trying to get Java working and didn't get around to operator overloading by release date. Either way, it greatly increases the readability of Java in 95% of all cases, at the expense of making vector math a bit wordy.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See here and here if you don't understand the example.)
Someone also provided me with this list, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only just started with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be very brief, so if you don't understand what it's getting at check out the link.)
A static method in Java does not translate to a Python classmethod
A switch statement in Java translates to a hash table in Python
Don't use XML
Getters and setters are evil (hey, I'm just quoting :) )
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
Don't put everything into classes. Python's built-in list and dictionaries will take you far.
Don't worry about keeping one class per module. Divide modules by purpose, not by class.
Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
Just do this:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition must be wrong.
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethod decorator. It also has a classmethod decorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java switch statement in Java can be implemented several ways. First, and foremost, it's usually an if elif elif elif construct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.
Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not required in Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the property decorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something not to look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidental use of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter is a certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
The next most important thing is that you will have to get over the notion that the type of an object controls what it may do; rather, the code controls what objects must be able to support at runtime (this is by virtue of duck-typing).
Oh, and use native lists and dicts (not customized descendants) as far as possible.
The way exceptions are treated in Python is different from
how they are treated in Java. While in Java the advice
is to use exceptions only for exceptional conditions this is not
so with Python.
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
As Alex Martelli puts in his book Python in a Nutshell
the exception mechanism with other languages (and applicable to Java)
is LBYL (Look Before You Leap) :
is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
A corrollary to "Don't use classes for everything": callbacks.
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListener with its actionPerformed() method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
button.onclick(lambda: print("click!\n"))
I can perfectly see why Clojure is really good for concurrent programming. I can see the advantages of FP also in this regard.
But clearly, not every line of code that we write is part of a thread or needs concurrent access. For those parts of the code (the more simple and sequential piece of code) what is it that Java really missed that Clojure provided?
Were features like Multimethods, Dynamic binding, Destructuring bind really missed in Java?
I supposed my question can also be framed as:
If Clojure did not have the
Concurrency features that it had and
the whole Immutability/Mutability
issue was not of our concern, then
what other features Clojure provides
that would make you use it instead of
Java ?
Were features like Multimethods, Dynamic binding, Destructuring bind really missed in Java?
Yes. Also...
First-class functions. Delicious first-class functions. This isn't just an FP thing. There's a good reason people are clamoring for closures in Java 7.
Code-is-data. This is the benefit of any Lisp. Lisp code isn't just blobs of text you feed into the mouth of a compiler and never see again, it's structures of lists and vectors and symbols and literals that you can manipulate progammatically. This leads to powerful macros and first-class Symbols and lots of other goodies. It leads to a highly extensible and powerful language.
Clojure has better control and looping constructs and the ability to create your own via macros and first-class functions. Java has for and foreach and while (and didn't even have foreach for years). Clojure has map, filter, reduce, mapcat, lots of do forms, lots of if and when forms, list comprehensions via for, and so on. If these didn't exist, you could write them yourself. In Java you get to wait a decade for a committee to (maybe) approve such features.
Minus those dealing with static typing, all of the features set for Java 7, Clojure either already has or could have trivially. "Automatic resource management", Clojure has as with-open. "Language support for collections", Clojure (and Ruby, Perl, Python...) has already. "Strings in switch", Clojure has more powerful case-like constructs like condp, and whatever else you can think up. You could write any of these yourself in a dozen lines of Clojure.
Concise syntax for lists, maps, arrays, sets, sorted sets, sorted maps etc. and nearly interchangeable use of them all thanks to the seq abstraction. Literal support for regexes, characters, anonymous functions, etc.
Java has mandatory checked exceptions, which are annoying; Clojure doesn't.
Java syntax is verbose and irregular. Clojure syntax is concise and regular. Even Java written in Clojure is often more concise than Java written in Java thanks to macros like -> and doto, and constructs like proxy and (soon) reify.
Java code has too much mandatory boilerplate and endless repetition. public static void main(String[] args){...} etc. Clojure has next to none of this boilerplate, while sacrificing little to nothing in terms of expressiveness or power. Even other statically typed languages today seem to be going the way of type inference. There's good reason you need a bulky Java-centric IDE to write and endlessly "refactor" Java code; writing it by hand would drive you insane and wear your fingers down to nubs.
In Java everything is a class or interface, whether it should be or not, which is a cause of unnecessary complexity. There are many programs that have to be mangled beyond recognition to fit into an OOP style. Clojure lets you avoid this. A nice rant to this effect. Clojure focuses largely on verbs.
Interactive programming via REPL is fun. Compile/run/debug cycles are not. Clojure still compiles to .class files if you want it; in the meantime you can sit in the middle of your code and tinker freely while it's running.
Clojure's metadata and sane equality testing are enjoyable to work with. As are its auto-promotion of int to long to Bigint, native handling of rational numbers, and so on.
Dynamic typing leads to shorter, more generic thus more reusable thus more powerful code than static typing. (This is a highly debatable point, obviously, so I put it last.)
The popularity of Scala and Groovy and JRuby and Jython and endless other JVM-languages-that-aren't-Java should be seen as a good indication that while the JVM is good, Java-the-language is unpleasant for many people.
Brian has summarized it really well. Here is something that really impressed me. (From the book Programming Clojure by Stuart Halloway)
Java code, from the Apache Commons:
public class StringUtils {
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
}
Here is a similar implementation in Clojure:
(defn blank? [s] (every? #(Character/isWhitespace %) s))
Well for one there is generally a lot less "ceremony" in Clojure. Languages like Python and Ruby have this advantage over Java as well (thus the popularity of JRuby, Jython).
But note there are times when verbosity cannot be avoided in Java though there might be a clear pattern. Clojure's macros are a huge win here- even over other similarly dynamic languages.
Another thing to consider is that Clojure programs tend to be concurrency safe. So if you decide down the road to make a particular application concurrent, it won't be too painful. Without making alot of decisions up front this will be considerably more difficult with Java.
Also wondering if Clojure would have a clear advantage over Java if it lacked strong concurrency primitives and immutability is kind of like saying, "Well what if Clojure wasn't Clojure?"
Besides the dynamic nature of Python (and the syntax), what are some of the major features of the Python language that Java doesn't have, and vice versa?
List comprehensions. I often find myself filtering/mapping lists, and being able to say [line.replace("spam","eggs") for line in open("somefile.txt") if line.startswith("nee")] is really nice.
Functions are first class objects. They can be passed as parameters to other functions, defined inside other function, and have lexical scope. This makes it really easy to say things like people.sort(key=lambda p: p.age) and thus sort a bunch of people on their age without having to define a custom comparator class or something equally verbose.
Everything is an object. Java has basic types which aren't objects, which is why many classes in the standard library define 9 different versions of functions (for boolean, byte, char, double, float, int, long, Object, short). Array.sort is a good example. Autoboxing helps, although it makes things awkward when something turns out to be null.
Properties. Python lets you create classes with read-only fields, lazily-generated fields, as well as fields which are checked upon assignment to make sure they're never 0 or null or whatever you want to guard against, etc.'
Default and keyword arguments. In Java if you want a constructor that can take up to 5 optional arguments, you must define 6 different versions of that constructor. And there's no way at all to say Student(name="Eli", age=25)
Functions can only return 1 thing. In Python you have tuple assignment, so you can say spam, eggs = nee() but in Java you'd need to either resort to mutable out parameters or have a custom class with 2 fields and then have two additional lines of code to extract those fields.
Built-in syntax for lists and dictionaries.
Operator Overloading.
Generally better designed libraries. For example, to parse an XML document in Java, you say
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("test.xml");
and in Python you say
doc = parse("test.xml")
Anyway, I could go on and on with further examples, but Python is just overall a much more flexible and expressive language. It's also dynamically typed, which I really like, but which comes with some disadvantages.
Java has much better performance than Python and has way better tool support. Sometimes those things matter a lot and Java is the better language than Python for a task; I continue to use Java for some new projects despite liking Python a lot more. But as a language I think Python is superior for most things I find myself needing to accomplish.
I think this pair of articles by Philip J. Eby does a great job discussing the differences between the two languages (mostly about philosophy/mentality rather than specific language features).
Python is Not Java
Java is Not Python, either
One key difference in Python is significant whitespace. This puts a lot of people off - me too for a long time - but once you get going it seems natural and makes much more sense than ;s everywhere.
From a personal perspective, Python has the following benefits over Java:
No Checked Exceptions
Optional Arguments
Much less boilerplate and less verbose generally
Other than those, this page on the Python Wiki is a good place to look with lots of links to interesting articles.
With Jython you can have both. It's only at Python 2.2, but still very useful if you need an embedded interpreter that has access to the Java runtime.
Apart from what Eli Courtwright said:
I find iterators in Python more concise. You can use for i in something, and it works with pretty much everything. Yeah, Java has gotten better since 1.5, but for example you can iterate through a string in python with this same construct.
Introspection: In python you can get at runtime information about an object or a module about its symbols, methods, or even its docstrings. You can also instantiate them dynamically. Java has some of this, but usually in Java it takes half a page of code to get an instance of a class, whereas in Python it is about 3 lines. And as far as I know the docstrings thing is not available in Java