\( \newcommand{\NOT}{\neg} \newcommand{\AND}{\wedge} \newcommand{\OR}{\vee} \newcommand{\XOR}{\oplus} \newcommand{\IMP}{\Rightarrow} \newcommand{\IFF}{\Leftrightarrow} \newcommand{\TRUE}{\text{True}\xspace} \newcommand{\FALSE}{\text{False}\xspace} \newcommand{\IN}{\,{\in}\,} \newcommand{\NOTIN}{\,{\notin}\,} \newcommand{\TO}{\rightarrow} \newcommand{\DIV}{\mid} \newcommand{\NDIV}{\nmid} \newcommand{\MOD}[1]{\pmod{#1}} \newcommand{\MODS}[1]{\ (\text{mod}\ #1)} \newcommand{\N}{\mathbb N} \newcommand{\Z}{\mathbb Z} \newcommand{\Q}{\mathbb Q} \newcommand{\R}{\mathbb R} \newcommand{\C}{\mathbb C} \newcommand{\cA}{\mathcal A} \newcommand{\cB}{\mathcal B} \newcommand{\cC}{\mathcal C} \newcommand{\cD}{\mathcal D} \newcommand{\cE}{\mathcal E} \newcommand{\cF}{\mathcal F} \newcommand{\cG}{\mathcal G} \newcommand{\cH}{\mathcal H} \newcommand{\cI}{\mathcal I} \newcommand{\cJ}{\mathcal J} \newcommand{\cL}{\mathcal L} \newcommand{\cK}{\mathcal K} \newcommand{\cN}{\mathcal N} \newcommand{\cO}{\mathcal O} \newcommand{\cP}{\mathcal P} \newcommand{\cQ}{\mathcal Q} \newcommand{\cS}{\mathcal S} \newcommand{\cT}{\mathcal T} \newcommand{\cV}{\mathcal V} \newcommand{\cW}{\mathcal W} \newcommand{\cZ}{\mathcal Z} \newcommand{\emp}{\emptyset} \newcommand{\bs}{\backslash} \newcommand{\floor}[1]{\left \lfloor #1 \right \rfloor} \newcommand{\ceil}[1]{\left \lceil #1 \right \rceil} \newcommand{\abs}[1]{\left | #1 \right |} \newcommand{\xspace}{} \newcommand{\proofheader}[1]{\underline{\textbf{#1}}} \)

2.4 Methods: Functions Belonging to a Data Type

The built-in functions we’ve studied so far all have one interesting property in common: they can all be given arguments of at least two different data types. For example, abs works with both int and float, len and sorted work with set and list (and others), and type and help work with values of absolutely any data type. In fact, this is true for almost all built-in functions in Python, as part of the design of the language itself.

However, Python’s data types also support operations that are specific to that particular data type: for example, there are many operations we can perform on strings that are specific to textual data, and that wouldn’t make sense for other data types.

Python comes with many functions that perform these operations, but handles them a bit differently than the functions we’ve seen so far. A function that is defined as part of a data type is called a method. The terms function and method are sometimes blurred in other programming languages, but for us in Python these terms have precise and distinct meanings! All methods are functions, but not all functions are methods. For example, the built-in functions we looked at above are all not methods. We refer to functions that are not methods as top-level functions. So far we’ve only seen how to define top-level functions, but we’ll learn later how to define methods too. But for now, let’s look at a few examples of built-in methods of various Python data types.

String method examples: str.lower and str.split

One str method in Python is called lower, and has the effect of taking a string like 'David' and returning a new string with all uppercase letters turned into lowercase: 'david'. To call this method, we start with a value of type str, followed by a period (.) and then the name of the method.

>>> 'David'.lower()
'david'
>>> 'MARIO'.lower()
'mario'
>>> my_string = 'Hello'
>>> my_string.lower()
'hello'

Note the empty () following the method name! Even though it looks like we are not passing in any arguments to the function, that’s not exactly true: the expression before the . is treated as an argument. More formally, when the Python interpreter evaluates my_string.lower(), it does the following:

  1. It evaluates variable my_string, obtaining the value 'Hello'.
  2. It looks up the type of 'Hello', which is str.
  3. It looks up the lower method of str.
  4. It calls str.lower with 'Hello' as the argument. In other words, the interpreter automatically passes the value to the left of the dot (in this case, 'Hello') as the method’s first parameter.

Here is an example of a second, very useful string method that splits a string into words (based on where spaces appear in the string):

>>> 'David is cool'.split()
['David', 'is', 'cool']

Finally, you can use the built-in help function to learn more about methods, just like any other function. Just remember that the full name for the method should include the type—for example, str.lower, not just lower.

>>> help(str.lower)
Help on method_descriptor:

lower(self, /)
    Return a copy of the string converted to lowercase.

Set method examples: set.union and set.intersection

Next we’ll look at two Python set methods that perform fundamental set operations. First, let’s define these operations on mathematical sets. Let \(A\) and \(B\) be sets.

Python’s set data type defines two methods, set.union and set.intersection, that implement these two operations:

>>> set1 = {1, 2, 3}
>>> set2 = {2, 10, 20}
>>> set1.union(set2)
{1, 2, 3, 20, 10}
>>> set1.intersection(set2)
{2}

These methods also illustrate how to pass additional arguments to methods beyond just the value to the left of the .. For example, when the Python interpreter evaluates set1.union(set2):

  1. It evaluates variable set1, obtaining the value {1, 2, 3}.
  2. It looks up the type of {1, 2, 3}, which is set.
  3. It looks up the union method of set.
  4. It calls set.union with {1, 2, 3} and the value of set2, {2, 10, 20}, as the two arguments.

List method examples: list.count

And finally, here is an example of a list method that takes a list and a value, and returns the number of times that value appears in the list. Remember that unlike sets, lists can contain duplicates! So you can view list.count as a generalization of the in operator for lists.

>>> numbers = [10, 20, 30, 10, 20, 40, 20]
>>> numbers.count(20)
3

References