The naming guide

A common set of naming rules can be applied on variables, methods, functions, and properties. The names of classes and modules also play an important role in namespace construction, and in turn in code readability. This mini-guide provides common patterns and antipatterns for picking their names.

Using the has or is prefix for Boolean elements

When an element holds a Boolean value, the is and has prefixes provide a natural way to make it more readable in its namespace:

class DB:
    is_connected = False
    has_cache = False

Using plurals for variables that are collections

When an element is holding a collection, it is a good idea to use a plural form. Some mappings can also benefit from this when they are exposed like sequences:

class DB:
    connected_users = ['Tarek']
    tables = {
        'Customer': ['id', 'first_name', 'last_name']
    }

Using explicit names for dictionaries

When a variable holds a mapping, you should use an explicit name when possible. For example, if a dict holds a person's address, it can be named persons_addresses:

persons_addresses = {'Bill': '6565 Monty Road', 
                     'Pamela': '45 Python street'}
persons_addresses['Pamela']
'45 Python street'

Avoiding generic names

Using terms such as list, dict, sequence, or elements, even for local variables, is evil if your code is not building a new abstract datatype. It makes the code hard to read, understand, and use. Using a built-in name has to be avoided as well, to avoid shadowing it in the current namespace. Generic verbs should also be avoided, unless they have a meaning in the namespace.

Instead, domain-specific terms should be used:

def compute(data):  # too generic
    for element in data:
        yield element ** 2


def squares(numbers):  # better
    for number in numbers:
        yield number ** 2

There is also a list of prefixes and suffixes that despite being very common in programming should be, in fact, avoided in function and class names:

  • Manager
  • Object
  • Do, handle, or perform

The reason for this is that they are vague, ambiguous, and do not add any value to the actual name. Jeff Atwood, the co-founder of Discourse and Stack Overflow, has a very good article on this topic, which can be found on his blog at http://blog.codinghorror.com/i-shall-call-it-somethingmanager/.

There is also a list of package names that should be avoided. Everything that does not give any clue about its content can do a lot of harm to the project in the long term. Names such as misc, tools, utils, common, or core have a very strong tendency to become endless bags of various unrelated code pieces of very poor quality that seem to grow in size exponentially. In most cases, the existence of such a module is a sign of laziness or lack of enough design efforts. Enthusiasts of such module names can simply forestall the future and rename them to trash or dumpster because this is exactly how their teammates will eventually treat such modules.

In most cases, it is almost always better to have more small modules, even with very little content, but with names that well reflect what is inside. To be honest, there is nothing inherently wrong with names such as utils and common and it is possible to use them responsibly. But the reality shows that in many cases they instead become a stub for dangerous structural antipatterns that proliferate very fast. And if you don't act fast enough, you may not ever be able get rid of them. So the best approach is simply to avoid such risky organizational patterns and nip them in the bud if introduced by other people working on a project.

Avoiding existing names

It is bad practice to use names that already exist in the context because it makes reading and, more specifically, debugging very confusing:

>>> def bad_citizen():
...     os = 1
...     import pdb; pdb.set_trace()
...     return os
...
>>> bad_citizen()
> <stdin>(4)bad_citizen()
(Pdb) os
1
(Pdb) import os
(Pdb) c
<module 'os' from '/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/os.pyc'>

In this example, the os name was shadowed by the code. Both built-ins and module names from the standard library should be avoided.

Try to create original names, even if they are local to the context. For keywords, a trailing underscore is a way to avoid a collision:

def xapian_query(terms, or_=True):
    """if or_ is true, terms are combined with the OR clause"""
    ...

Note that class is often replaced by klass or cls:

def factory(klass, *args, **kwargs):
    return klass(*args, **kwargs)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset