Java dev learning Python: what concepts do I need to wrap the head around

javalanguage-featurespython

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.

Best Answer

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.