Python for Programmers: Naming Conventions
Welcome to the Naming Conventions lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Most Python identifiers (the names of variables, functions, methods, etc.) follow the snake_case convention: all lowercase, with underscores between words.
>
number_of_snakes = 10eggs_per_snake = 5def get_egg_count():return number_of_snakes * eggs_per_snakeget_egg_count()Result:
50
The snake_case convention also applies to strings that are only intended for programmers. For example, strings used as dictionary keys normally follow snake_case.
>
settings_dict = {"max_temperature": 40,"power_mode": "performance",}settings_dict.get("min_temperature", 20)Result:
20
There are three notable exceptions to the snake_case convention: classes, constants, and private attributes. First, Python classes are normally UpperCamelCased.
>
class WaterTank:def __init__(self, starting_amount):self.remaining_amount = starting_amountdef drain(self, amount):if amount > self.remaining_amount:raise ValueError("Not enough water left in the tank")self.remaining_amount -= amountwater_tank = WaterTank(1000)water_tank.drain(200)water_tank.remaining_amountResult:
800
In JavaScript and many other languages, function calls and instantiation are clearly separated by the
newkeyword:user()calls a function, whilenew User()instantiates an object.In Python, these use exactly the same syntax. Without additional context, we can't tell whether
f()is calling a function namedfor instantiating a class namedf. UpperCamelCased class names reduce the ambiguity:user()is probably a function call, butUser()is probably instantiating a class.The second exception to snake_case is that constants are conventionally SHOUTED.
>
INCHES_PER_FOOT = 12def feet_to_inches(feet):return feet * INCHES_PER_FOOTfeet_to_inches(5)Result:
60
The third exception is private attributes and methods, which shouldn't be accessed from outside of their class. The convention is to prefix private attribute and method names with an underscore, like
_my_private_method. For example, we might have aFixedSizeBufferclass with a private_max_sizeattribute.>
# A class that only remembers up to n values at a time. When we add more than n# values, it drops the oldest ones to make room.class FixedSizeBuffer:def __init__(self, max_size):self._max_size = max_sizeself.values = []def add(self, value):self.values.append(value)if len(self.values) > self._max_size:self.values = self.values[-self._max_size:]- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
buffer = FixedSizeBuffer(2)buffer.add("Amir")buffer.add("Betty")buffer.add("Cindy")buffer.valuesResult:
['Betty', 'Cindy']
It's important to note that constants and private methods are only naming conventions that Python programmers agree on. They're not language features, and Python doesn't enforce them!
If a name is UPPERCASE, then we all agree that its value shouldn't change. If an attribute starts with an
_, then we all agree that we won't call it from outside the class.However, Python will let us reassign "constants".
>
# In Python, constants are SHOUTED by convention. But it's only a convention,# and Python will let us change the value of a "constant".PI = 3.14PI = 12PIResult:
12
It will also let us read the "private"
_max_sizeattribute from outside the class.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
# In Python, attributes and methods whose names begin with `_` are private, but# it's only a convention. Python will let us access "private" attributes.buffer = FixedSizeBuffer(2)buffer._max_sizeResult:
2
(Python does have a separate language feature for private attributes. It's similar to the naming convention that we already saw: if an attribute name starts with
__, Python will make some weak attempts to prevent access from outside of the class. But this is only a weak guarantee, and the feature is rarely used, so we won't discuss it in detail. We recommend sticking to a single underscore for private attributes and methods:self._max_size, notself.__max_size.)There's one last naming convention issue to discuss. As in most languages, we can't use keywords like
class,def, andwhileas variable names. However, we might write a function that takes a class as an argument, then does something with the class.The convention is to append an underscore to the argument name:
class_. Some Python code usesklassinstead. We recommend the trailing underscore, since that pattern works for any keyword, not justclass.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
def instantiate_class(class_, *args, **kwargs):return class_(*args, **kwargs)buffer = instantiate_class(FixedSizeBuffer, 3)buffer.add(1)buffer.add(2)buffer.add(3)buffer.add(4)buffer.valuesResult:
[2, 3, 4]
We've seen a total of five conventions in this lesson:
- snake_case variable and method names
- CamelCaseClasses
- CONSTANTS
- _private_attributes
class_/klass
The Python community follows these conventions quite closely, but Python itself sometimes violates them.
Some parts of the standard library use camelCase, like the
unittestmodule's.assertEqualsmethod. That's becauseunittestcopied the older JUnit API long ago. It was originally written in Java wherecamelCaseis the norm.In other cases, Python's evolution over time has left inconsistencies. For example, many built-in "functions" like
int,range, etc. are actually classes, even though they're lower-cased. In earlier versions of Python, these were truly functions. When they were changed into classes, the Python core team maintained backwards compatibility by leaving the original lowercase names in place.Sometimes, Python is just plain inconsistent. For example, dictionaries'
.setdefaultand.popitemmethods both combine two words without an underscore. (.set_defaultand.pop_itemwould be more consistent.)But Python's biggest inconsistency is probably
TrueandFalse. They're not classes, but they're named like classes!Complying with PEP 8 is relatively easy. The Black Python formatting tool is very popular, and it formats code to be PEP 8 compliant.
Although there are exceptions, Python code is still more consistent than most languages. PEP 8 is almost universally followed, so you're likely to see snake_cased methods and UpperCamelCased classes in any Python project.