June 3, 2017
4 min. read
This post is part of the Python Tips series.
There are a whole bunch of underscores in Python. If you are new to Python, this may seem weird. There is a reason behind the flatness. There are even special names for them, under when you have a single underscore and dunder when two underscores are used (for double underscore).
There are many uses of single underscores in Python. We will hit a few common and easy to explain right away and get them over with.
Python variable and function naming uses underscores to separate words. So a variable might be
number_of_semicolons. They should not be
numberOfSemicolons. Constants (which are just variables you don’t change) should be all caps and underscore separated like
Functions should be exactly the same format as variable, such as
cause_destruction(method_to_use), depending on if you are a super hero or super villain.
Weak Internal Hiding
If you prefix your class variable or method, this is a signal to those using your class that you are expecting them to behave as adults and leave it be. Modifying it could cause issues. The user can still call the method or set the variable, but can take note of possibly being bad.
If you are using
@property methods in a class, I like using the name of the property with an underscore prefix.
When you must define a variable, method or function that is named the same as a Python keyword, it is common to use a trailing underscore. However, I find most situations can be handled better by being more descriptive instead. We type once and read many times. And good IDEs also allows auto complete.
Strong Internal Hiding
We saw that we can tell uses of our class methods that they are off limits with a single underscore. However, we can assure that they can’t call them with double underscores. Ok, that is kind of a lie. You cannot call them directly, but if you understand how the name mangling works, you can make your call to it. This idea is that most people won’t do that. If they do, they deserve what they get.
Wanna know how name mangling works, so you can be bad too?
If you have a class named
Bob, and a method named
Bob.__weave() will not work. However,
Bob._Bob__weave() will work. But don’t do it unless you have a real reason.
There are tons of magic methods in Python. These look a little weird when defining classes and modules, but allow a way of making your objects easy to use and simple for users. These are called dunders. The reason why they are wrapped with duoble underscores, is that you might want to use the name for a standard method.
Lets cover how many of these methods work.
Common Class Methods
__init__ - We already covered this one, which handles initialization of an new instance.
__new__ - This isn’t as common as
__init__, but is called before and when you need to handle the creation of the instance.
__del__ - This is technically a destructor, but you should not use it. Structure you code so you don’t need it. Python is not a language built for destructors, like C++.
__del__ really should be gone (in my opinion). This is called when the GC decides to clean up your object, not when it goes out of scope. Exceptions raised in
__del__ are ignored. One place that might be an OK use is if you are cleaning up ctypes. Much better to use a context manager if possible.
__exit__ are required for creation of context managers. Look for an upcoming post on context managers.
__call__ method allows your instance to be called. This is different than
__init__ which allows you to call your class and create and instance.
__str__ - String representation of the object.
__repr__ - Allows you to return a representation of the class in a string format. Will be used in a
__str__ does not exist.
__len__ - Provide implementation for the
__getitem__ - Returns item for iterator
__next__ - Gets next item in iterator.
__reversed__ - Allows reversing of an iterator
Default comparison sometimes just works, but you can overload so that it works for the default data value of your object.
__eq__ - True if equal to other
__lt__ - True if self is less than other
Despite them often being called magic methods, think of them as just dunder methods and tools. If you use them properly, your objects and modules will just feel more Pythonic to use.
Hopefully this has demystified the underscores of Python. They are not magical, just features of the language.
Part 5 of 9 in the Python Tips series.