I need help choosing proper names for variables with long actual names. I have read pep8 docs, but I couln't find addressed such issue.
Would you rename very_long_variable_name
to something like vry_lng_var_nm
or would you leave it as it is. I notice that pythons build in libraries have very short names and I'd like to follow the conventions if it exists for this case.
I know I can name it something not very descriptive and add description, which would explain its meaning, but what do you think should be the variables name.
There is no absolute necessity for short names, what is important is clarity. A good rule of thumb is to use different means to provide different level of details about your program:
Variable names should describe what things are.
Your code itself already describes how things are done.
Comments and docstrings should describe why things are done this way.
In the end, obeying these rules will oftentimes help you choose concise variable names by removing the superfluous information they contain.
PEP8 does not necessarily recommend short names. It does so only for modules and type variable names. What is important is for names to be clear and to use a consistent convention across a module.
I usually avoid abbreviations, except for well-known ones. Hence, very_long_variable_name
is better than vry_lng_var_nm
. You should use short names if it helps readability, not for the sake of having short names.
Yet, that does not answer the question of what makes a name clear. Here are a few advice.
This one is actually part of PEP8.
The name of a variable, in particular function names, should describe what it does and not how it does it. It is already the role of the code you write to describe how things are done. For instance, the built-in function sorted
is not called timsort
(which is the algorithm CPython uses for sorting).
Similarly, if you have a list of numbers stored in a variable, you should describe what this list of numbers represents. Say it is a list of students' grades, you could then call it student_grades
, but not list_of_numbers
.
If you have multiple variables which represent the same kind of things, you can qualitatively describe what each variable contains.
good_students = filter(lambda s: s.grade >= 90, students)
average_students = filter(lambda s: 60 <= s.grade < 90, students)
bad_students = filter(lambda s: s.grade < 60, students)
Notice how I described students qualitatively with good
, average
and bad
instead of quantitatively with names such as students_with_grades_above_90
. This describes what the categories of students are without going into the details of how we build each category.
Remember that the people reading your code are programmers. If they need to know how things are done, they will read your code. Your variables provide a higher level of abstraction that describes what is happening without necessarily describing how.
Variable names are at a very high level of abstraction. The code you write describes how things are done at a low level of abstraction. Use comments and doc strings for everything that falls in between, such as higher-level explanations of how things are done and why things are done that way.
Adding documentation in comments and doc strings fills the gap between the level of detail given by names and that given by the code. If you feel it is important that the reader knows how and why things are done, then this information should go in comments.
In this example, a variable was given a long and very specific name: students_with_grades_above_90
. We may feel the need for a very specific name because the function is undocumented.
def get_good_students(students):
return filter(lambda s: s.grade > 90, students)
students_with_grades_above_90 = get_good_students(students)
By adding some documentation, we can relax how specific that name is. Making it both shorter and more abstract. If the reader is not sure about what get_good_students
returns, they should look at the function's docstring.
def get_good_students(students):
"""Return students with grade above 90"""
return filter(lambda s: s.grade > 90, students)
good_students = get_good_students(students)
If you feel you need a very specific name for a function, it might be that the function is too specific itself.
# Very long name because very specific behaviour
def get_students_with_grade_above_90(students):
return filter(lambda s: s.grade > 90, students)
# Adding a level of abstraction shortens our method name here
def get_students_above(grade, students):
return filter(lambda s: s.grade > grade, students)
# What we mean here is very clear and the code is reusable
good_students = get_students_above(90, students)
Also notice how using grade
as a parameter allowed to remove it from the function's name without loss of clarity.
Encapsulate logic in shorter scopes. This way, you don't need to give as much detail with variable names, as it can be looked up quickly a few lines above. A rule of thumb is to make your functions fit in your IDE without scrolling. Encapsulate some logic in a new function if you go beyond that.
# line 6
names = ['John', 'Jane']
... # Hundreds...
... # and hundreds...
... # of lines of code
# line 371
# Wait what was names again?
if 'Kath' in names:
...
Here I lost track of what names
was and scrolling up will make me lose track of even more. This is better:
# line 6
names = ['John', 'Jane']
# I encapsulate part of the logic in another function to keep scope short
x = some_function()
y = maybe_a_second_function(x)
# line 13
# Sure I can lookup names, it is right above
if 'Kath' in names:
...
The last but not least is to devote time thinking about how you can make your code more readable. Remember that code is not only read by computers, it is read by programmers too! The best code is the code that everyone can read, and thus everyone can improve.