Common Python Design Questions and Explanations
This article explains why Python uses indentation for block grouping, how floating‑point arithmetic works, why strings are immutable, the purpose of the explicit self parameter, the absence of assignment in expressions, and many other design decisions that shape Python's syntax and runtime behavior.
01. Why use indentation to group statements?
Guido van Rossum considers indentation an elegant way to group code, improving readability because there are no explicit start/end brackets, so the parser’s view matches the human reader’s view.
<code>if (x <= y)
x++
y--
z++
</code>In languages like C, missing brackets can cause confusion; Python avoids this by using indentation.
02. Why do simple arithmetic operations sometimes give strange results?
Python’s float type stores numbers as C double values, which have limited binary precision, leading to results such as 1.2 - 1.00 producing 0.19999999999999996 .
03. Why are floating‑point calculations inaccurate?
Many decimal numbers cannot be represented exactly in binary; the stored value is an approximation. CPython uses 53‑bit precision, giving about 15‑16 decimal digits of accuracy.
04. Why are Python strings immutable?
Immutability allows the interpreter to allocate fixed space for a string, improving performance and enabling strings to be used as dictionary keys.
05. Why must methods explicitly use self ?
Explicit self makes it clear whether an attribute belongs to the instance or is a local variable, and it simplifies method resolution and inheritance.
06. Why can’t assignment appear inside expressions?
Allowing assignment in expressions can hide subtle bugs (e.g., writing if (x = 0) instead of if (x == 0) ). Python forces assignments to be statements to avoid this class of errors.
07. Why are some operations methods (e.g., list.index() ) while others are functions (e.g., len() )?
Prefix notation (methods) is often more readable for operations that are tightly bound to an object, while functions like len() convey the nature of the operation (returning a length) without needing to know the object’s type.
08. Why is join() a string method rather than a list method?
The separator string calls join() to iterate over a sequence of strings, which mirrors the design of other sequence‑related methods and keeps the API consistent.
09. How fast are exceptions?
When no exception is raised, try/except blocks have negligible overhead. Raising and catching an exception is expensive, so it should be used for exceptional cases, not regular control flow.
10. Why doesn’t Python have a switch / case statement?
Python encourages the use of if…elif…else chains or dictionary dispatch tables to select among many alternatives.
11. Can Python simulate threads without OS‑level threads?
Standard CPython relies on C‑level threads, but Stackless Python provides a redesigned interpreter that avoids C stack usage.
12. Why can’t lambda expressions contain statements?
Python’s syntax does not allow statements inside expressions; lambdas are meant as concise, single‑expression functions.
13. Can Python be compiled to machine code or other languages?
Tools like Cython, Nuitka, and VOC can translate Python code to C, C++, or Java, respectively.
14. How does Python manage memory?
CPython uses reference counting plus a cyclic‑garbage collector; other implementations (Jython, PyPy) use different strategies.
15. Why doesn’t CPython use a traditional garbage collector?
Reference counting provides deterministic deallocation, and integrating a traditional GC would complicate embedding and portability.
16. Why doesn’t CPython free all memory on exit?
Objects reachable from the global namespace may not be released, especially those involved in reference cycles; the atexit module can be used to clean up explicitly.
17. Why are there separate tuple and list types?
Tuples are immutable and can be used as dictionary keys; lists are mutable collections intended for ordered, changeable data.
18. How are lists implemented in CPython?
Lists are dynamic arrays of object references, providing O(1) indexing and amortized O(1) appends.
19. How are dictionaries implemented in CPython?
Dicts are resizable hash tables; keys are hashed to locate slots, giving average O(1) lookup.
20. Why must dictionary keys be immutable?
Mutable objects could change their hash value after insertion, breaking the hash table invariants.
21. Why does list.sort() not return the sorted list?
Sorting in place avoids the overhead of copying the list; use the built‑in sorted() function when a new list is needed.
22. How to specify and enforce interface specifications in Python?
Python’s abc module defines abstract base classes; isinstance and issubclass can check compliance, and testing frameworks (doctest, unittest) help enforce behavior.
23. Why is there no goto ?
Python encourages structured control flow; a goto can be simulated with exceptions but is discouraged.
24. Why can’t raw strings end with a backslash?
An odd number of trailing backslashes would escape the closing quote, leaving the string unterminated.
25. Why doesn’t Python have a with statement for attribute assignment?
Dynamic attribute resolution makes it ambiguous which attribute is being set; the existing with is reserved for context managers.
26. Why do if / while / def / class statements require a colon?
Colons improve readability and help editors determine where a block begins.
27. Why are trailing commas allowed in lists, tuples, and dicts?
Trailing commas simplify adding, reordering, or generating elements and prevent subtle syntax errors.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.