38

Background: I've run through a few tutorials and written some small projects. All is going well enough using Google and StackOverflow.

Several times in the last few days I've found myself wondering "what am I missing?" - I feel that I'm still thinking in Java as I write in Python.

This question over at StackOverflow is full of tips about what resources to read up on for learning Python, but I still feel that I'm a Java developer with a dictionary (no pun intended) to translate into Python.

What I really want to do is refactor my head to be able to write Pythonic Python instead of Java disguised as Python, without losing my Java skills either.

So, the crux of my question is: what concepts does a Java dev really need to learn to think Pythonic? This includes anything that needs to be unlearned.

Note: I am asking about language concepts, not about language syntax.

1
  • 9
    Let go of the idea that programming is supposed to be hard.
    – Job
    Commented Feb 13, 2011 at 17:40

5 Answers 5

41

A few points in addition to what was already said:

  • Python is dynamic. Creation of a class is an executable statement, as is import of a module; it can be made conditional. A class can be altered after creation; this allows for easy metaprogramming and AOP.

  • There are no interfaces; duck typing rules. If you desperately need them, there are 'abstract base classes (ABCs)', but usually you don't miss interfaces, since there's no static type checking anyway.

  • Though everything is an object, functions come before objects. Having just functions (and no classes) in a module is perfectly fine.

  • Everything is a first-class entity. Passing functions as parameters, returning them and assigning to variables is the norm. Ditto for classes. Methods are just functions; you can handle an instance method as if it were a regular function, pass it around, etc.

  • Use built-in dicts, sets, lists, and tuples. Lists and dicts are mutable, tuples aren't. All of them are very efficient and syntactically succinct. Get used to returning several values from a function using a tuple (you don't even need parentheses). Get used to replacing complex hierarchies of very simple objects with contraptions made of plain lists, tuples, and dicts ('hashtables'), it simplifies life.

  • Python has a fair bit of FP support; learn list comprehensions and then iterators and generators. These help a lot.

  • Any operators can be overloaded by defining proper methods, so addition or comparison can return whatever you want. Remember this working with things like SQLAlchemy.

  • There's no null, only None, a full-fledged object. You can print None just fine, etc. Passing None where another instance is expected results usually in a AttributeError, not an NPE, sometimes farther down the execution pipeline.

  • Due to the fully dynamic nature of Python, you have nearly no static checks. You can refer to a name that never exists in your program (e.g. a typo), or only gets defined in a particular execution path, and nothing will remind you of it until execution actually hits this reference and a NameError is raised. Be careful with the scope of your variables, and write more unit tests.

  • Due to the fully dynamic nature of Python, objects are nearly always malleable. Usually you can add fields and methods even to an instance and thus inadvertently delete or overwrite its state or method set. Be careful assigning attributes. This allows for interesting possibilities, too :)

  • There are no symbolic constants, only variables. Check that you don't inadvertently overwrite a 'constant'. If you want to be positively sure that you can't overwrite a constant, use a function or a property (which is a function in disguise).

  • Python's threads are good for I/O-bound processing, but not for CPU-bound. Don't try to speed up a computational task by running it in parallel threads.

5
  • +1 very good points. Nitpicking: None usually causes AttributeError (but doesn't matter, you usually don't need it anyway) and you can (and in some cases should) write immutable objects (e.g. through namedtuple).
    – user7043
    Commented Feb 14, 2011 at 16:07
  • @danlan: thanks, I corrected the text :) Yes, you can create immutable objects. But objects that you generally create by creating a regular class and then instances of it are very mutable, unless you take a number of special measures. The fact that assignment to an undefined instance attribute usually silently defines it instead of causing an error may be a surprise for a Java programmer.
    – 9000
    Commented Feb 14, 2011 at 17:07
  • 1
    Python (and other FP languages) replaces more verbose code build of simpler building blocks with compact code build on more complex building blocks. Think RISC vs CISC processors.
    – Paul
    Commented Mar 30, 2012 at 14:36
  • 1
    I would add sets to the data structures.
    – sakisk
    Commented Sep 19, 2012 at 11:42
  • 2
    A little over 3 years since I asked this question. I have to say this advice has stood up very well.
    – LRE
    Commented Mar 31, 2014 at 0:25
14

Read this article: Python is not Java. (Plus most of the other articles in the sidebar are worth reading, although not Java-related.) The article gives some great pointers on how Java programmers can unintentionally mis-use Python (and how not to).

1
  • 6
    "XML is not the answer." - that goes well beyond Java v Python ;-)
    – LRE
    Commented Feb 13, 2011 at 20:45
3

I moved from Java to Python and one of the most useful things I found was being able to test code from the command line interpreter. Type python into the command line and run your code from there until you get it right.

Frameworks were also a bit less defined in Python. There are 10s of web frame works just for starters. Django more or less replaces Spring and SQL Alchemy for Hibernate.

2

One important thing would be to understand dynamic typing; another is that objects are mutable and public. Less important, at least initially, is name binding vs variables.

class MyJob:
    pass        # an empty class
job = MyJob()
job.title = "Ruler of Omicron Persei 8"
job.startDate = "2086"
job.startDate = time.strptime("2035/01/02", "%Y/%m/%d")
myjobtitle = job.title
import new
def myjobduration(self, when):  # create a function
    return when - time.mktime(self.startDate)
MyJob.duration = myjobduration
job.duration(time.time()) # now

Here, myjobtitle and the value of job.title point to the same object. The class attribute job.startDate has first been assigned a string, then to a time object. And through out it all, the job instance and even the class itself could be changed dynamically.

1

You may also want to take a look at Jython. It may only support Python 2.5, but we find it really powerful to be able to rapid prototype with Python and then rewrite in Java later if necessary.

Based on my answer to What should I think about when switching from Python to Java? as that question has now been closed as a duplicate of this one!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.