How Do You Choose Python Function Names?

How Do You Choose Python Function Names?

by Stephen Gruppetta Jul 10, 2024 basics

One of the hardest decisions in programming is choosing names. Programmers often use this phrase to highight the challenges of selecting Python function names. It may be an exaggeration, but there’s still a lot of truth in it.

There are some hard rules you can’t break when naming Python functions and other objects. There are also other conventions and best practices that don’t raise errors when you break them, but they’re still important when writing Pythonic code.

Choosing the ideal Python function names makes your code more readable and easier to maintain. Code with well-chosen names can also be less prone to bugs.

In this tutorial, you’ll learn about the rules and conventions for naming Python functions and why they’re important. So, how do you choose Python function names?

Take the Quiz: Test your knowledge with our interactive “How Do You Choose Python Function Names?” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

How Do You Choose Python Function Names?

In this quiz, you'll test your understanding of how to choose Python function names. By working through this quiz, you'll revisit the rules and conventions for naming Python functions and why they're important for writing Pythonic code.

In Short: Use Descriptive Python Function Names Using snake_case

In Python, the labels you use to refer to objects are called identifiers or names. You set a name for a Python function when you use the def keyword.

When creating Python names, you can use uppercase and lowercase letters, the digits 0 to 9, and the underscore (_). However, you can’t use digits as the first character. You can use some other Unicode characters in Python identifiers, but not all Unicode characters are valid. Not even 🐍 is valid!

Still, it’s preferable to use only the Latin characters present in ASCII. The Latin characters are easier to type and more universally found on most keyboards. Using other characters rarely improves readability and can be a source of bugs.

Here are some syntactically valid and invalid names for Python functions and other objects:

Name Validity Notes
number Valid
first_name Valid
first name Invalid No whitespace allowed
first_10_numbers Valid
10_numbers Invalid No digits allowed at the start of names
_name Valid
greeting! Invalid No ASCII punctuation allowed except for the underscore (_)
café Valid Not recommended
你好 Valid Not recommended
hello⁀world Valid Not recommended—connector punctuation characters and other marks are valid characters

However, Python has conventions about naming functions that go beyond these rules. One of the core Python Enhancement Proposals, PEP 8, defines Python’s style guide, which includes naming conventions.

According to PEP 8 style guidelines, Python functions should be named using lowercase letters and with an underscore separating words. This style is often referred to as snake case. For example, get_text() is a better function name than getText() in Python.

Function names should also describe the actions being performed by the function clearly and concisely whenever possible. For example, for a function that calculates the total value of an online order, calculate_total() is a better name than total().

You’ll explore these conventions and best practices in more detail in the following sections of this tutorial.

What Case Should You Use for Python Function Names?

Several character cases, like snake case and camel case, are used in programming for identifiers to name the various entities. Programming languages have their own preferences, so the right style for one language may not be suitable for another.

Python functions are generally written in snake case. When you use this format, all the letters are lowercase, including the first letter, and you use an underscore to separate words. You don’t need to use an underscore if the function name includes only one word. The following function names are examples of snake case:

  • find_winner()
  • save()

Both function names include lowercase letters, and one of them has two English words separated by an underscore. You can also use the underscore at the beginning or end of a function name. However, there are conventions outlining when you should use the underscore in this way.

You can use a single leading underscore, such as with _find_winner(), to indicate that a function is meant only for internal use. An object with a leading single underscore in its name can be used internally within a module or a class. While Python doesn’t enforce private variables or functions, a leading underscore is an accepted convention to show the programmer’s intent.

A single trailing underscore is used by convention when you want to avoid a conflict with existing Python names or keywords. For example, you can’t use the name import for a function since import is a keyword. You can’t use keywords as names for functions or other objects. You can choose a different name, but you can also add a trailing underscore to create import_(), which is a valid name.

You can also use a single trailing underscore if you wish to reuse the name of a built-in function or other object. For example, if you want to define a function that you’d like to call max, you can name your function max_() to avoid conflict with the built-in function max().

Unlike the case with the keyword import, max() is not a keyword but a built-in function. Therefore, you could define your function using the same name, max(), but it’s generally preferable to avoid this approach to prevent confusion and ensure you can still use the built-in function.

Double leading underscores are also used for attributes in classes. This notation invokes name mangling, which makes it harder for a user to access the attribute and prevents subclasses from accessing them. You’ll read more about name mangling and attributes with double leading underscores later.

Snake case is the preferred option for Python function names as outlined in PEP 8. However, Python doesn’t enforce its use and you may occasionally see Python functions named using camel case. Camel case, which is also referred to as lower camel case or mixed case, is popular in other programming languages. An example of camel case is findWinner().

Often, this style is used in Python by programmers who mainly code in other languages or in modules that have historically always used this case, such as the logging module. This module follows names used in similar packages in other programming languages and it dates back to a time when Python’s naming conventions weren’t well-established.

It’s best to avoid using camel case for Python functions unless you’re working on an existing code base that already uses this format.

Why Should You Use Descriptive Names for Python Function Names?

Readability is a key principle of modern programming and plays an important role in Python. You can make your code more readable by choosing function names that clearly describe the function’s purpose.

Consider the following function:

Python
def init(n):
    return " ".join(f"{i[0]}." for i in n.split())

You can determine what action this function performs if you’re familiar with the .join() and .split() string methods and the generator expression syntax, which is similar to the syntax used for list comprehensions.

However, the function name init and the parameter name n are not descriptive and don’t clearly show what the function is meant to do. The name init can also cause some confusion due to its similarity to the special method .__init__().

Now, look at this version of the same function:

Python
def get_initials(full_name):
    return " ".join(f"{name[0]}." for name in full_name.split())

The intended purpose of this function is clearer in this version since the function name get_initials() describes the function’s action. You can confirm the function works as you expect:

Python
>>> def get_initials(full_name):
...     return " ".join(f"{name[0]}." for name in full_name.split())

>>> get_initials("James Clerk Maxwell")
J. C. M.
>>> get_initials("Richard Feynman")
R. F.

The function and parameter names help you understand the code in the function’s body. The function calls confirm that get_initials() returns the initials from any full name.

The parameter name full_name also helps with readability. The line defining the function now reads as get initials (from) full name. The word from is missing but can easily be implied by someone reading the code. You can also use get_initials_from() if you wish to be more explicit.

This naming convention enables you to use functions as higher-level building blocks since the name tells you what it does, and you don’t need to be concerned about how the function is implemented at a lower level. A function can be used as a black box once it’s defined and tested, and a descriptive name is an important part of the function’s documentation.

You also want to avoid unnecessarily long names. Long names make the code more verbose and lead to longer lines, which may require scrolling or splitting into multiple lines. Therefore, get_initials() is a reasonable compromise between readability and name length.

Programmers have different preferences, and you may also need to adapt to naming practices within teams or in existing code bases you work on. There isn’t just one right answer when deciding how to name a function.

Here’s another example. You write a function that finds the number of vowels in a text. You could name your function find_number_of_vowels(). This name is clear and descriptive, and many programmers may choose this name.

However, others may prefer a shorter, sufficiently readable version: find_num_vowels(). Shortening number to num is a well-understood abbreviation, and the preposition of can also be safely omitted. Some programmers may even choose to go with find_n_vowels(). The shorter version puts more emphasis on the important part of the name, which in this case, is the word vowel.

So, why are short names still used if they’re not recommended? In the early days of programming, short names were required since code had to be punched on cards, and the available memory and line-length were limited. Single-letter variable and function names were common, and these practices can still be seen in some present-day code.

However, there’s no longer a need for short names since the limitations from the early years are not relevant today, and modern editors have helpful tools such as name autocompletion.

Also, since today’s computers can deal with higher demands, programs are longer and more complex than in the early days of computing. As a result, code readability has become more important over the years, and choosing function names is a tool programmers can use to make code easier to read and maintain. Readable code can also minimize the likelihood of bugs.

What Are the Naming Conventions for Methods?

Methods are functions defined within a class. The naming convention for methods is identical to regular functions. Therefore, you should also write method names using snake case, and they should describe the method’s actions.

You learned earlier in this tutorial that there are conventions around when to use underscores at the beginning or end of a name. The most common use of underscores at either end of a method name is associated with special methods. These are methods called by Python to perform specific operations on an object.

Special method names include two leading underscores and two trailing underscores, such as with .__init__(). The pair of double underscores has led to these methods being informally called dunder methods.

To demonstrate a number of methods and their names, you can create a BankAccount class and a script called bank_account.py:

Python bank_account.py
class BankAccount:
    def __init__(self, account_number, balance):
        self.account_number = account_number
        self.balance = balance

    def __repr__(self):
        return (
          f"{type(self).__name__}({self.account_number}, {self.balance})"
        )

The class includes two special methods, which both have two leading underscores and two trailing underscores as part of their names:

  • .__init__() is called when you create an instance of a class. It initializes the object.
  • .__repr__() defines the official string representation for an object, which includes information about the class name and its arguments.

Keep in mind that you can’t choose the names for special methods since they’re an integral part of the Python language. You also shouldn’t use names with two leading underscores and two trailing underscores for any methods other than Python’s special methods.

You can add more methods to this class:

Python bank_account.py
class BankAccount:
    # ...

    def get_balance(self):
        return self.balance

    def withdraw(self, amount):
        ...

The first method you add is .get_balance(), which follows the function naming conventions you learned about earlier:

  • The method name is in snake case.
  • The name clearly describes the method. The first word in the name is the verb get to clarify the action performed by the method.

Like function names, method names should be a verb or start with a verb to highlight the action they perform whenever appropriate.

The next method you define is .withdraw(), which also follows the same conventions. You call this method by passing an amount to it, such as .withdraw(50). Therefore, the call makes it clear that you wish to withdraw 50 (dollars, say).

This method doesn’t have any code yet. It should perform the following actions:

  1. Verify that the account’s balance is greater than or equal to the amount to withdraw
  2. Deduct the amount from the account’s balance if there are sufficient funds
  3. Return True if the withdrawal is successful or False if no funds are withdrawn

You could define two methods called verify_funds() and deduct_funds() to use in this method and other parts of the class definition. However, you’ll choose slightly modified names for these methods. First, consider the method to verify there are sufficient funds in the account.

You want to use this method within the class definition, but you don’t want to make it part of the interface for this class. A user of this class doesn’t need to call this method. To state your intention about how this method should be used, you can add a single leading underscore to the method name:

Python bank_account.py
class BankAccount:
    # ...

    def _verify_funds(self, amount):
        return self.balance >= amount

    # ...

This notation doesn’t prevent someone using the class from calling this method directly. You can confirm this in a REPL session:

Python
>>> from bank_account import BankAccount
>>> debit_account = BankAccount(1111, 50)
>>> debit_account._verify_funds(25)
True

Some Python tools will use the single leading underscore convention to assist you when programming. For example, here are the autocomplete suggestions provided by PyCharm, a popular Python IDE:

PyCharm screenshot showing that attributes with leading underscores are not shown for autocompletion

The suggestions show the two data attributes, .account_number and .balance, and the two methods, .withdraw() and .get_balance(). The rest of the suggestions are Python’s special methods.

The method you defined with a leading underscore, ._verify_funds(), is not shown and won’t autocomplete with PyCharm’s default setup. However, you can still type it in full and call the function, as you did in the REPL session. Some languages refer to these attributes as private. However, the preferred term in Python for attributes with a leading underscore is non-public.

You also need a method to deduct funds from the account and to write the code in .withdraw() at this stage:

Python bank_account.py
class BankAccount:
    def __init__(self, account_number, balance):
        self.account_number = account_number
        self.balance = balance

    def __repr__(self):
        return (
          f"{type(self).__name__}({self.account_number}, {self.balance})"
        )

    def _verify_funds(self, amount):
        return self.balance >= amount

    def _deduct_funds(self, amount):
        self.balance -= amount

    def get_balance(self):
        return self.balance

    def withdraw(self, amount):
        if self._verify_funds(amount):
            self._deduct_funds(amount)
            return True
        return False

The .withdraw() method calls ._verify_funds() and ._deduct_funds(). These methods can be easily accessed within a class definition since this is where they’re meant to be used.

You add two more methods to this class:

Python bank_account.py
class BankAccount:
    def __init__(self, account_number, balance):
        self.account_number = account_number
        self.balance = balance

    def __repr__(self):
        return (
          f"{type(self).__name__}({self.account_number}, {self.balance})"
        )

    def _verify_funds(self, amount):
        return self.balance >= amount

    def _deduct_funds(self, amount):
        self.balance -= amount

    def _add_funds(self, amount):
        self.balance += amount

    def get_balance(self):
        return self.balance

    def withdraw(self, amount):
        if self._verify_funds(amount):
            self._deduct_funds(amount)
            return True
        return False

    def deposit(self, amount):
        self._add_funds(amount)
        return True

The .deposit() method is part of the class’s interface since it doesn’t have any leading underscores in its name. You can use this method whenever you create an instance of the class. However, ._add_funds() has a leading underscore to make it non-public.

You can test this class in a new REPL session:

Python
>>> from bank_account import BankAccount
>>> debit_account = BankAccount(1111, 50)
>>> debit_account.get_balance()
50

>>> debit_account.withdraw(32.50)
True
>>> debit_account.get_balance()
17.5

>>> debit_account.withdraw(22.75)
False
>>> debit_account.get_balance()
17.5

>>> debit_account.deposit(10)
True
>>> debit_account.get_balance()
27.5

When you use the class to create an instance, you can perform all the actions using instance methods that don’t have leading underscores. The first .withdraw() call is successful, and it updates the bank account’s balance. The second .withdraw() call is unsuccessful since the amount requested is greater than the account’s balance. The method returns False. You call .deposit() to increase the amount of funds in the account.

What’s the Difference Between Naming Functions, Variables, and Classes?

You’ve learned about the conventions for naming Python functions and how you usually choose descriptive names with lowercase characters and underscores to separate words. How do these rules and guidelines compare with the conventions for naming variables and classes?

The naming rules that Python enforces apply to all names, including the names of variables and classes. Therefore, variable and class names can’t start with a digit and can’t have ASCII punctuation marks other than the underscore. Python raises a SyntaxError if you break these naming rules.

In addition to these rules that Python enforces, there are conventions for naming variables and classes. Variables follow a similar convention as function names and should be named using lowercase characters with underscores separating words. Here are some examples:

  • first_name
  • data
  • selling_price

It’s preferable to avoid single-letter variable names or short abbreviations unless these are acceptable within specific domains. An example of an exception to this guideline is when single-letter variables are used in mathematical applications, where the letters are commonly used in mathematics and science.

Variable names should describe the data they represent to make the code more readable. Often, the variable name is a noun. When the name represents a constant value, it’s conventional to use uppercase characters, such as TIME_LIMIT.

Class names use a different case. The first letter of each word is capitalized, and there are no underscores separating words. Programmers refer to this case using different terms. Here are some of them:

  • CapitalizedWords
  • CamelCase
  • UpperCamelCase
  • PascalCase

All these names refer to the same format. When a class name includes a single word, only the first letter is capitalized. Here are some examples of class names:

  • BankAccount
  • Person
  • TennisPlayer

Note that most of the built-in core data types don’t follow this convention. The names list, dict, str, and many more are all lowercase even though they’re the names of classes. Classes in other standard libraries and third-party modules may also fail to follow this convention, such as numpy.ndarray. However, it’s advisable to follow the camel case naming convention when creating your custom classes.

This case is also used for the names of type variables when using type checking, such as Protocol and MutableSequence. Exception names are also in camel case, such as SyntaxError and ModuleNotFoundError.

Conclusion

In this tutorial, you learned how to choose Python function names that follow the core naming rules and the conventions defined by Python’s style guide. Function names contain all lowercase letters. When function names contain more than one English word, you use underscores to connect these words. Function names should also be descriptive to make the code more readable and easier to maintain.

Python doesn’t enforce these naming guidelines. However, most programmers follow these conventions for consistency and to improve readability. You can keep these conventions in mind the next time you need to choose a name for a new function.

Take the Quiz: Test your knowledge with our interactive “How Do You Choose Python Function Names?” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

How Do You Choose Python Function Names?

In this quiz, you'll test your understanding of how to choose Python function names. By working through this quiz, you'll revisit the rules and conventions for naming Python functions and why they're important for writing Pythonic code.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Stephen Gruppetta

Stephen worked as a research physicist in the past, developing imaging systems to detect eye disease. He now teaches coding in Python to kids and adults. And he's almost finished writing his first Python coding book for beginners

» More about Stephen

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.


Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Topics: basics