From Java & JavaScript to Python
You already know how to program. This appendix maps what you know from Java and JavaScript onto Python, and flags the habits that cause bugs. Read it first, or come back whenever something feels "almost but not quite" familiar.
You will refresh
- Syntax, typing and the "everything is a reference" object model.
- Equality,
None, truthiness and numbers: the four biggest sources of surprises. - Collections, loops, functions and classes, side by side.
- Interfaces vs duck typing, and exceptions without
throws. - Classic design patterns, done the Pythonic way.
1. Syntax at a glance
Python uses indentation instead of braces, newlines instead of semicolons, and words instead of symbols for logic.
| Java / JS | Python |
|---|---|
{ … } blocks | : plus 4-space indentation |
// comment, /* */ | # comment; docstrings """…""" |
&& || ! | and or not |
true false null / undefined | True False None |
else if | elif |
x++ | x += 1 |
cond ? a : b | a if cond else b |
camelCase methods | snake_case (PEP 8) |
In Python: Chapter 1 (indentation) and Chapter 3 (if/elif, the conditional expression).
Quick check: how do you write x = flag ? 1 : 0?
x = 1 if flag else 0
2. Dynamic typing (with optional hints)
In Java, a variable has a type. In Python, only objects have types; a variable is just a name that can point to anything. Type hints exist, but Python doesn't check them at run time. Tools like mypy do. Unlike JS, Python is strongly typed: it never converts types silently.
In Python: Chapter 5 (annotations), Chapter 1 (the TypeError).
Quick check: what does int("7") + 1 give?
8. You convert explicitly with int(), float() or str().
3. Everything is an object; variables are references
Python has no primitives: 3, True and functions are all objects. Every variable holds a reference, and assignment never copies. It is exactly how Java object references and JS object variables behave, just applied to everything. Mutability is what decides whether sharing matters.
| Immutable (safe to share) | Mutable (shared changes are visible) |
|---|---|
int float bool str tuple frozenset frozendict bytes None | list dict set bytearray, most user objects |
In Python: Chapter 2 (aliasing), Chapter 5 (passing by object reference), Chapter 11 (names and objects).
Quick check: after t = (1, [2]); t[1].append(3), what is t?
(1, [2, 3]). The tuple is immutable, but the list inside it is not.
4. Equality and identity: ==, is, None
Python's == compares values, so it is Java's .equals(), and you can use it on strings. is compares identity (the same object), which is Java's == on references. Use is only for singletons like None. There is one "nothing" value, None; there is no undefined.
⚠️ x is 5 or s is "abc" might seem to work, because of interning, but it is unreliable, and Python warns: SyntaxWarning: "is" with 'int' literal.
In Python: Chapter 7 (more on conditions), Chapter 11 (__eq__).
Quick check: which do you write, if x == None or if x is None?
if x is None. It is faster and can't be fooled by a custom __eq__.
5. Truthiness, Python vs JavaScript
Both languages have "falsy" values, but the lists differ. In Python, empty containers are false, which JS doesn't do for [] and {}.
| Value | JS | Python |
|---|---|---|
[] / {} | truthy | false |
"", 0 | falsy | false |
"0", "false" | truthy | true |
NaN | falsy | float("nan") is true |
null / None | falsy | false |
In Python: Chapter 3 (truthiness), Chapter 7 (and/or return operands).
Quick check: what is [] or "default"?
'default'. The empty list is false, so or returns its second operand.
6. Numbers
int has unlimited size (no overflow), / always returns a float, and // floors toward minus infinity. Floats are IEEE-754 doubles, like Java's double and JS's number.
In Python: Chapter 2 (numbers and floats), Chapter 14 (Decimal).
Quick check: Java's -7 / 2 is -3. How do you get -3 in Python?
int(-7 / 2), which truncates toward zero. -7 // 2 gives -4.
7. Strings
Strings are immutable Unicode, as in Java. There is no char type (a character is a 1-length str), and no StringBuilder: collect parts in a list and "".join() them. Template literals become f-strings.
| Java / JS | Python |
|---|---|
`Hi ${name}` / String.format | f"Hi {name}" |
s.length() / s.length | len(s) |
s.substring(1, 3) / s.slice(1, 3) | s[1:3] |
s.contains("x") / s.includes("x") | "x" in s |
String.join(",", list) / arr.join(",") | ",".join(items) |
s.trim() | s.strip() |
In Python: Chapter 2 (text), Chapter 9 (f-strings).
Quick check: how do you get the last 3 characters of s?
s[-3:]
8. Collections
| Java | JavaScript | Python |
|---|---|---|
ArrayList | Array | list [1, 2] |
HashMap / LinkedHashMap | Object / Map | dict {"k": 1} (keeps insertion order) |
HashSet | Set | set {1, 2} |
record / small arrays | small arrays | tuple (1, "a"), namedtuple, @dataclass |
ArrayDeque | — | collections.deque |
PriorityQueue | — | heapq |
stream().filter().map() | .filter().map() | comprehensions [f(x) for x in xs if p(x)] |
In Python: Chapters 6 and 7.
Quick check: what happens with prices["coffee"]?
KeyError: a missing key raises; it doesn't return null. Use .get() for a default.
9. Loops
There is no C-style for (;;). for always iterates over items, and you ask for indexes with enumerate(). while is the same as in Java. Loops can have an else that runs when no break happened.
In Python: Chapter 3, and Chapter 7 (looping techniques).
Quick check: how do you loop over two lists in parallel?
for a, b in zip(xs, ys): (add strict=True to catch lists of different lengths).
10. Functions
Functions are first-class objects, like in JS. There is no overloading: use default values, keyword arguments, *args and **kwargs instead. Lambdas can only contain a single expression. Closures capture variables, not values.
In Python: Chapter 5.
Quick check: why is def f(items=[]) dangerous?
The default list is created once and shared between calls. Use None and create the list inside the function.
11. Classes
this becomes an explicit self parameter. The constructor is __init__, and there is no new. There are no access modifiers: _name means "internal" by convention. static becomes a class variable, @classmethod or @staticmethod. Getters and setters become plain attributes, or a @property if you need logic later.
In Python: Chapter 11.
Quick check: what is the Python version of Java's record Point(int x, int y)?
@dataclass(frozen=True) class Point: x: int; y: int
12. Interfaces → duck typing, ABCs and Protocols
Python cares whether an object has the right methods, not what it declares itself to be. That is duck typing. When you want a formal contract, use an abstract base class (abc.ABC), which errors if you instantiate an incomplete subclass, or a typing.Protocol, which is structural and checked only by type checkers, like TypeScript interfaces.
In Python: Chapter 11 (polymorphism without interfaces), Chapter 12 (the iterator protocol is duck typing).
Quick check: what makes an object usable in a for loop?
An __iter__ method (or __getitem__). No interface declaration is needed: that is duck typing.
13. Exceptions
try/catch/finally becomes try/except/finally, plus an else clause. throw becomes raise. There are no checked exceptions and no throws clause. The Python style is EAFP: try the operation and handle the failure, instead of checking every condition first.
In Python: Chapter 10.
Quick check: what is the Python version of Java's try-with-resources?
The with statement: with open(path) as f: …
14. Design patterns, the Pythonic way
Because functions are objects and modules are singletons, many Gang-of-Four patterns shrink to a few lines in Python, or disappear entirely.
| Pattern | Typical Java | Pythonic |
|---|---|---|
| Singleton | private constructor + getInstance() | a module: it is imported once (Chapter 8) |
| Strategy / Command | an interface + classes | pass a function (key=, a dispatch dict) |
| Iterator | Iterator<T> class | a generator with yield (Chapter 12) |
| Factory method | a static factory | a @classmethod like from_dict (Chapter 11) |
| Builder | a fluent builder class | keyword arguments with defaults, or a dataclass |
| Decorator | wrapper classes | @decorator functions (@property, @dataclass) |
| Template method | an abstract class | an ABC, or simply pass the varying step as a function |
| Observer | listener interfaces | a list of callables |
In Python: Chapter 5 (functions as values), Chapter 8 (modules), Chapter 16 (the dispatch table in cli.py).
Quick check: what is the simplest Python Singleton?
A module-level object, e.g. config = Config() in settings.py. Every import settings shares it.
Recap: prerequisite feature → where you see it in Python
| You know (Java/JS) | Python equivalent | Where in this book |
|---|---|---|
| braces, semicolons | indentation, newlines | Ch. 1, 3 |
| static types | dynamic types + optional hints | Ch. 5 |
| object references | every name is a reference | Ch. 2, 11 |
.equals() / === | ==; is for identity | Ch. 7 |
null / undefined | None | Ch. 5 |
| for-each, iterators | for … in, generators | Ch. 3, 12 |
switch | match | Ch. 4 |
| overloading, varargs | defaults, *args, **kwargs | Ch. 5 |
| ArrayList, HashMap, HashSet | list, dict, set | Ch. 6, 7 |
| packages, imports | modules, packages, import | Ch. 8 |
| try/catch, throws | try/except, no checked exceptions | Ch. 10 |
| classes, interfaces | classes, duck typing, ABCs | Ch. 11 |
| JUnit, Maven/npm | unittest/pytest, venv + pip | Ch. 13, 15 |
Exercises
Exercise 1 🟢 easy refactor it
Translate to Python: for (int i = 0; i < names.length; i++) { System.out.println(i + ": " + names[i]); }
Show solution
enumerate replaces the index counter. The f-string replaces the string concatenation.
Exercise 2 🟢 easy predict the output
What does this print? print([] == [], [] is [], bool([]), bool("False"))
Show solution
True False False True. The two lists have equal values but are different objects. An empty list is false, and any non-empty string is true.
Exercise 3 🟢 easy fix the bug
A JS developer wrote this. Fix all four problems.
Show solution
function becomes def, braces become a colon and indentation, let and const disappear, and of becomes in. Avoid naming a variable sum, because it hides the built-in sum(), which does this whole job anyway.
Exercise 4 🟢 easy explain why
Why does Python not need getX() and setX() methods?
Show solution
A public attribute can later become a @property without changing any caller's code (obj.x still works). So you start simple and add logic only when you need it.
Exercise 5 🟡 medium refactor it
Translate this Java stream: list.stream().filter(s -> s.length() > 3).map(String::toUpperCase).collect(Collectors.toList())
Show solution
A comprehension does the filter and the map in one readable expression.
Exercise 6 🟡 medium build it
Implement the Strategy pattern for shipping costs without any classes: standard (a flat €5), express (€5 plus 10% of the order) and free (orders over €100 ship free, otherwise standard). Choose a strategy by name.
Show solution
Each strategy is just a function stored in a dict. Adding a new strategy means adding one function and one dict entry.
Exercise 7 🟡 medium predict the output
What does this print?
Show solution
[1, 2, 3, 4] Ana. The list was mutated through the shared reference. name += "!" created a new string and only rebound the local name, because strings are immutable.
Exercise 8 🟡 medium build it
Write an Observer: a class EventBus with subscribe(fn) and publish(event), using plain functions as listeners.
Show solution
No listener interface is needed: anything callable works. Returning fn from subscribe makes it usable as a decorator, as the @bus.subscribe line shows.
Exercise 9 🔴 hard explain why
In Java, Integer a = 1000, b = 1000; a == b is false. In Python, 1000 == 1000 is always True, but a is b may be either. Explain both languages' behaviour.
Show solution
Java's == on boxed Integers compares references, and only small values (−128 to 127) are cached. Python's == always compares values. Python's is compares identity, and whether two equal ints are the same object is an implementation detail (CPython caches small ints and reuses constants). So never use is for numbers or strings.
Exercise 10 🔴 hard mini-project
Port this Java-style design to idiomatic Python: an interface Shape with area(), classes Circle and Rect, a ShapeFactory.create(String type, double... args), and a loop that prints the shapes sorted by area. Use an ABC, dataclasses, a dict-based factory, and sorted(key=…).
Show solution
Classes are first-class values, so the "factory" is a dict lookup. Dataclasses remove the constructor boilerplate, and key= replaces a Comparator.