Python myth busting

Icon class
icon_class_computed
fab fa-python
icon_class
fab fa-python

Some real or imagined myths, erroneous claims, and misunderstandings about Python.


"Python is an interpreted language, not a compiled language"

Well, actually, it's not quite so simple, and it depends on the implementation. The CPython implementation "compiles" Python code first to intermediate byte code – in a form understandable by the Python Virtual Machine (PVM) – which is then executed in the PVM line-by-line (interpreted). PyPy uses Just-In-Time (JIT) compilation for faster execution.

Python is usually described as an interpreted language because it executes code line by line, but that doesn't mean there aren't also compilation steps.

This answer from a Python interview questions guide is not quite correct:

16. What is an Interpreted language?

An Interpreted language executes its statements line by line. Languages such as Python, Javascript, R, PHP, and Ruby are prime examples of Interpreted languages. Programs written in an interpreted language runs directly from the source code, with no intermediary compilation step.

Specifically, CPython DOES have an intermediary bytecode compilation step. It's just that it's all combined on-the-fly when you run Python code using CPython.


"That's not the Pythonic way! That's not how it's done in Python!"

Not much you can do about that one. Try explaining to someone who has only ever read Python forums about dictionaries that you can use classes, pure abstract classes as interfaces, and OO Design Patterns in Python, that it's a good idea to do so, and you can also combine OO aspects with functional aspects.


"Python is pass by value!" or "Python is pass by reference!"

Nope. Python primarily uses pass by object reference. And there are sadly heaps of authoritative looking articles and forum postings that get this wrong. You can however kind of wangle pass by reference if you really want to as an academic exercise.


"Python does not support inline assignment"

Actually, since Python 3.8+ you can use assignment expressions with the := operator. Some examples adapted from Stackoverflow:

if (x := 3) == 5:
    print("that's odd")

>>> x
3

>>> y = (x := 4) + 10
>>> y
14
>>> x
4

Whether it's a good idea to use the mechanism is a separate discussion, but it's supported.


"In Python you should use os.path for files and file paths"

Pathlib is in the standard library since Python 3.4 and is better for most tasks:


"Lambdas are a Python concept"

The lambdas concept is far broader than just the Python version of lambdas, and if you have experience with other coding language it can be confusing reading the terminology (especially incorrect use of the term closure) on some Python forums.


"In Python you should do everything with the low-level dict"

No. Except for the very simplest cases, encapsulate dict with clearly documented value-adding methods of classes (that may choose to always return immutable collection variants). And by the time you've fiddled with all of that dynamic data dictionary stuff you might as well have used a class. Separate WHAT the class should offers as services from HOW it does it (such as using a dict internally) and decouple clients where possible from the specific use of dict internally. And you can still also have methods that expose immutable versions of lower level data structures if you wish.


"Nobody uses lazy initialisation in Python (and I've never heard of cascading lazy initialisation)"

Cascading lazy initialisation (aka lazy instantiation) helps promote a more pure functional approach, helps reduce bad coupling, makes dependencies and the creation cycle clearer, and can be implemented in nearly any language. Dr Darren says:

Cascading lazy initialisation (pull lazy, pull lazy, pull lazy), is your very good friend.

"In Python you only use duck typing"

No! When coding with Python you may choose to rely on duck typing, but it's not a good idea. Use well defined classes and pure abstract classes (without any implementation) as interfaces.

And consider using intermediate abstract classes (with some implementation) for reuse, and note that this is NOT at odds with use of Python decorators or the Decorator pattern (which is a slightly different beast, see below).


"Nobody actually bothers to use pure abstract classes as interfaces in Python"

Dr Darren says:
I must be a nobody.

"Nobody uses OO Design Patterns in Python"

Dr Darren says:
I must be a nobody.

"Nobody models Python code using Systems Modeling Language (SysML)"

Dr Darren says:
I must be a nobody.

"Interfaces are not necessary in Python because it has duck typing"

Please remind me to never work with you. Both interfaces (in Python pure abstract classes) and abstract classes are crucial to robust design-by-contract and most OO Design Patterns. And in Python, too.


"Python is a functional language" or "Python is an object-oriented language"

Python is a multi-paradigm language with support for both object-oriented aspects and functional aspects, and the best Python coders can combine OO with functional:


"In Python you should use docstrings and make up your own syntax to represent function and method arguments and return types"

Consider: Sphinx (which uses reStructuredText (reST)), Pdoc, Epydoc, pydoctor, Doxygen, etc., or the Google format that can be interpreted by Sphinx using the Napoleon plugin.

BTW: The wonderful FastAPI mostly does a great job of pulling Markdown from API metadata for OpenAPI docs for Swagger and/or Redocly. There's little point in ALSO having docstrings for API functions if you've used the FastAPI metadata, because that would be WET.


"Python decorators are the same as the Gang-of-Four Decorator pattern."

Not quite. They are closely related, but not necessarily the same thing. Formally, the traditional GoF Decorator Pattern WITHOUT "annotations" (and without possible "annotation" metadata) relies on implementation against a specific contract. Python @decorators may be completely unbound to, well, anything.

Terminology: In Java, one can create custom @annotations (and there are lots of pre-defined ones. In Python, a @decorator is a bit like a Java annotation, not to be confused with Python type Annotations (aka function Annotations, hence the use of double quotes "annotations" above.

One main point of difference is that in the traditional Decorator pattern (as used for Java prior to introduction of @annotations and attributes in C++11), wrapping methods have the same signatures as delegate methods of wrapped objects. The very flexible and powerful arguments and keywords arguments system of Python (which has its pros and cons) and wildcarding means that a Python decorator can do pretty well anything it likes with whatever it likes, and can also mix-in @decorator metadata. It can be handy, but it can also make things harder to debug. Add in some functional injection and you've got the wild west.

Here's one way to test whether it's acting like a traditional GoF decorator (when using method decoration):

It should be possible to have a method name that is descriptive enough that any decoration is compatible with that description.

In other words, the client should not expect crazy undocumented side-effects. There is a clear target method – which may or may not be a decorating wrapper – and that method should meet some basic contract the client can anticipate.

Still not convinced? From Decorators I: Introduction to Python Decorators by Bruce Eckel:

Decorators vs. the Decorator Pattern

First, you need to understand that the word "decorator" was used with some trepidation, because there was concern that it would be completely confused with the Decorator pattern from the Design Patterns book. At one point other terms were considered for the feature, but "decorator" seems to be the one that sticks.

Indeed, you can use Python decorators to implement the Decorator pattern, but that's an extremely limited use of it.

It is not an accident that Bruce Eckel also wrote 'Thinking in Java' and 'Thinking in C++', that is, he has deep experience with many programming languages, not just Python!

In any case, the term decorator has over the years become somewhat broadened (and in many other languages including in Java), and is also sometimes misused to describe any function or method "annotation" mechanism.

Visit this article from 2019 for a good description of the traditional Decorator Pattern in Java.


"There are no pure Python web UI frameworks"

Reflex and NiceGUI are both pure Python web UI frameworks and both are both built on top of FastAPI.

This guide on Pure Python Web Development actually classifies the Django frontend also as "pure Python" (and recommends Hypergen for Django):

Django can be considered a pure Python web framework. In most cases, one still uses CSS and HTML, but one does not use Javascript.
Hypergen. Take a break from javascript. Write server-rendered reactive HTML liveviews for Django in pure python.

Visit also Top 10 Python Web Development Frameworks in 2025 (many of which are often combined with non-Python frontends such as React, Vue, and Angular), Front-end options for Django., and Choosing the Best Front-End Framework for Django.


PyCharm is better for Python than IntelliJ IDEA

In fact, both are from JetBrains, both are awesome, and PyCharm is just a Python-oriented variant of IntelliJ IDEA, which has all of the same Python support as PyCharm. Visit the JetBrains IntelliJ IDEA Ultimate vs PyCharm Pro comparison. From JetBrains themselves:

PyCharm Pro and the Python plugin for IntelliJ IDEA offer equivalent functionality.

The only possible benefit of using PyCharm Pro over IntelliJ IDEA and the Python Plugin (apart from PyCharm being cheaper) is that the UX for PyCharm Pro is more dedicated to Python related tasks (has fewer distractions due to non-Python feature menus and such). The disadvantage is that it doesn't have the same coverage of other coding and web languages.

BTW That comparison page link above seems to indicate that only PyCharm Pro offers Jupyter Notebook, but in fact all you to do in IntelliJ IDEA is enable the Jupyter Notebook plugin

.

JetBrains IntelliJ IDE is only for Java code development

JetBrains themselves describe IntelliJ IDEA as "The IDE for Professional Development in Java and Kotlin", and PyCharm as an "IDE for Python developers and data scientists (Python, Django, Jupyter)". But all you have to do in IntelliJ IDEA Ultimate is enable other plugins: Python, XML, JavaScript, HTML, CSS, PHP and a heap of frameworks are all there.

Visit also this comparison table for IntelliJ IDEA Ultimate vs IntelliJ IDEA Community Edition.


And finally, if you make the mistake during a Python job interview of mentioning that there are heaps of things that the Wolfram Language and  Wolfram Mathematica can do far better that Python.

"Python can do symbolic algebra just like Mathematica, because NumPy has support for some vector and matrix operations"

Nope!

"Python's SymPy can do symbolic algebra just like Mathematica"

SymPy is a Python library for symbolic mathematics. Dr Darren says:

Why anyone would use SymPy for symbolic algebra instead of  Wolfram Mathematica (or Maple) is beyond me. Maybe the argument is cost, but if your time is worth $$$ it might end up costing you more.

SymPy is clearly better than nothing, it's free, and it's lightweight, but it isn't the Wolfram Language, and it can't match a Mathematica Notebook.

The SageMath project is another free open source mathematics system for Python with some degree of symbolic algebra support. It also has a web interface system SageMatheCell for embedding Sage computations in web pages.


TIP: The Wolfram Client Library for Python

Did you know that you can call the Wolfram Engine (which is free for pre-production software development) and evaluate Wolfram Language code from Python? Did you know that it can directly handle Pandas DataFrames?


Notes
Relevant snippets (from other sources)
Visit also
Visit also (backlinks)
External links
Flags