Kitten under blanket
Photo by Mikhail Vasilyev on Unsplash

Man G. Ling

A Python Brain Teaser

Miki Tebeka
2 min readFeb 9, 2022

--

📚 Connect with us. Want to hear what’s new at The Pragmatic Bookshelf? Sign up for our newsletter. You’ll be the first to know about author speaking engagements, books in beta, new books in print, and promo codes that give you discounts of up to 40 percent.

Happy February! This month we have a Python brain teaser. See if you can tell what is causing the attribute error.

Let’s say you are tasked with writing a client to a REST API. Here’s the initial code:

Then you head over to your trusty IPython and run some initial tests:

What? You double-check and there’s no typo or Unicode shenanigans. Diving deeper, you look at the c attributes using the built-in vars and see the following:

You called the attribute __address, but it shows as _Client__address — why?

When an attribute starts with two underscores (like __address), Python mangles the attribute name.

Note: Special (dunder) methods such as __init__ are not mangled.

The reason for name mangling is to keep the attribute namespace free for subclasses. Say you want to write another version of client that uses sockets:

Both Clientand SocketClient use the same __address attribute! Imagine the fun bugs you’re going to chase :)

In Python, name mangling is not like private or protected in other languages. You can still access the attribute if you know the mangled name:

Inside the Clientclass, you will use the un-mangled name, __address. You don’t need to remember how names are mangled.

You can read more about name mangling in the Private Variables section of the Python documentation. Name mangling is not unique to Python, several other languages such as C, C++, Java, and even modern ones such as Rust and Swift, use the same mechanism to avoid name collision.

--

--