I'm confused about choosing names for my functions in Python. Sometimes Python built-in functions are imperative such as: print
function and string method find
. Sometimes they aren't such as: len
its name isn't imperative such as calculate_len
, for instance, and type
isn't find_type
.
I can understand that print
returns a value that we don't use (i.e None
) and does something (i.e it shows a string on the screen), so its name is imperative.
But len
returns a value that we use and does something (i.e. calculating how many items there are in a sequence or a mapping.) and its name isn't imperative. On the other hand, find
string method (as len
) returns a value that we use and does something, and its name is imperative.
What made ask this question is that I put a script that encrypt and decrypt string using Caesar cipher to being reviewed. The reviewer said that:
Just a gut feeling: functions do stuff. So a good name for a function
is an imperative: I'd userotate_letter
instead ofrotated_letter
.
rotated_letter
returns a single-letter string representing a letter rotated by a number. I don't know what is better, I used rotated_letter
as it returns a value, like randint
function in random module, it isn't generate_randint
.
So, in this case, how should I name a function that returns a value to be used? Should I make the name imperative or just a noun. In other cases it's obvious how to do it, such as boolean functions, such as is_even
and is_palindrome
we just make it like a yes/no question, and also functions that just do and return non-used values (i.e None
), such as print
and list method sort
.
Best Answer
Use verbs where reasonable, nouns if they are shorter and unambiguous
Most of the time, functions should be (imperative) verbs and classes, variables, and parameters should be nouns. Attributes should also be nouns, including those created using
@property
. This is especially the case for functions which have side effects.[1] If a function does return something, you should evaluate whether the verb adds something or is just "noise":make_list(foo)
vs.list(foo)
: The noun is easier to read than the verb. Also,list
is actually a class, and classes should be nouns.open(foo)
vs.file(foo)
: The verb is easier to read than the noun, and it makes more sense to give "options" to a verb than to a noun, so the noun was removed in Python 3.open()
remains the only "standard"[2] way to create file objects in Python 3.foo.get_bar()
vs.foo.bar()
vs.foo.bar
(assumefoo
andbar
are both nouns): The first option is right out, because the "get" doesn't add anything that we didn't already know. The second is appropriate if getting abar
out of afoo
is a potentially expensive operation and/or carries side effects (you might also considerBar(foo)
ifBar
is a class). The third is appropriate if this is a cheap operation with no side effects, and alternative implementations are unlikely to make it expensive.xs.sort()
vs.sorted(xs)
ifxs
is a list: The first is imperative: Sort the list. It modifies the list in-place and returns nothing. The second is declarative: A list that is sorted, which is precisely what it returns. Both are verbs.[1]: Usually returning a value and having side effects are mutually exclusive unless you have some compelling design reason to combine them. So a function that has side effects should probably not return anything and hence making it a noun would make very little sense.
[2]: There are some moderately lower-level operations in the
io
module which can be used to add or remove file buffering, automatic text en/decoding, etc., and these are mostly nouns because they are object-oriented classes. Most users do not need to play with these things directly; instead,open()
chooses an appropriate class and instantiates it automatically.