Python – How should I name functions that return values in Python

functionsnamingnaming-standardspythonpython-3.x

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 use rotate_letter instead of rotated_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 (assume foo and bar 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 a bar out of a foo is a potentially expensive operation and/or carries side effects (you might also consider Bar(foo) if Bar 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) if xs 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.

Related Topic