4.2 Defining Functions

You’ve called many built-in functions (int, float, print, input, type, sum, len, min and max) and a few functions from the statistics module (mean, median and mode). Each performed a single, well-defined task. You’ll often define and call custom functions. The following session defines a square function that calculates the square of its argument. Then it calls the function twice—once to square the int value 7 (producing the int value 49) and once to square the float value 2.5 (producing the float value 6.25):

In [1]: def square(number):
   ...:     """Calculate the square of number."""
   ...:     return number ** 2
   ...:

In [2]: square(7)
Out[2]: 49

In [3]: square(2.5)
Out[3]: 6.25

The statements defining the function in the first snippet are written only once, but may be called “to do their job” from many points throughout a program and as often as you like. Calling square with a non-numeric argument like 'hello' causes a TypeError because the exponentiation operator (**) works only with numeric values.

Defining a Custom Function

A function definition (like square in snippet [1]) begins with the def keyword, followed by the function name (square), a set of parentheses and a colon (:). Like variable identifiers, by convention function names should begin with a lowercase letter and in multiword names underscores should separate each word.

The required parentheses contain the function’s parameter list—a comma-separated list of parameters representing the data that the function needs to perform its task. Function square has only one parameter named number—the value to be squared.

If the parentheses are empty, the function does not use parameters to perform its task. Exercise 4.7 asks you to write a parameterless date_and_time function that displays the current date and time by reading it from your computer’s system clock.

The indented lines after the colon (:) are the function’s block, which consists of an optional docstring followed by the statements that perform the function’s task. We’ll soon point out the difference between a function’s block and a control statement’s suite.

Specifying a Custom Function’s Docstring

The Style Guide for Python Code says that the first line in a function’s block should be a docstring that briefly explains the function’s purpose:

"""Calculate the square of number."""

To provide more detail, you can use a multiline docstring—the style guide recommends starting with a brief explanation, followed by a blank line and the additional details.

Returning a Result to a Function’s Caller

When a function finishes executing, it returns control to its caller—that is, the line of code that called the function. In square’s block, the return statement:

return number ** 2

first squares number, then terminates the function and gives the result back to the caller. In this example, the first caller is square(7) in snippet [2], so IPython displays the result in Out[2]. Think of the return value, 49, as simply replacing the call square(7). So after the call, you’d have In [2]: 49, and that would indeed produce Out[2]: 49. The second caller square(2.5) is in snippet [3], so IPython displays the result 6.25 in Out[3].

Function calls also can be embedded in expressions. The following code calls square first, then print displays the result:

In [4]: print('The square of 7 is', square(7))
The square of 7 is 49

Here, too, think of the return value, 49, as simply replacing the call square(7), which would indeed produce the output shown above.

There are two other ways to return control from a function to its caller:

  • Executing a return statement without an expression terminates the function and implicitly returns the value None to the caller. The Python documentation states that None represents the absence of a value. None evaluates to False in conditions.

  • When there’s no return statement in a function, it implicitly returns the value None after executing the last statement in the function’s block.

What Happens When You Call a Function

The expression square(7) passes the argument 7 to square’s parameter number. Then square calculates number ** 2 and returns the result. The parameter number exists only during the function call. It’s created on each call to the function to receive the argument value, and it’s destroyed when the function returns its result to the caller.

Though we did not define variables in square’s block, it is possible to do so. A function’s parameters and variables defined in its block are all local variables—they can be used only inside the function and exist only while the function is executing. Trying to access a local variable outside its function’s block causes a NameError, indicating that the variable is not defined. We’ll soon see how a behind-the-scenes mechanism called the function-call stack supports the automatic creation and destruction of a function’s local variables—and helps the function return to its caller.

Accessing a Function’s Docstring via IPython’s Help Mechanism

IPython can help you learn about the modules and functions you intend to use in your code, as well as IPython itself. For example, to view a function’s docstring to learn how to use the function, type the function’s name followed by a question mark (?):

In [5]: square?
Signature: square(number)
Docstring: Calculate the square of number.
File:      ~/Documents/examples/ch04/<ipython-input-1-7268c8ff93a9>
Type:      function

For our square function, the information displayed includes:

  • The function’s name and parameter list—known as its signature.

  • The function’s docstring.

  • The name of the file containing the function’s definition. For a function in an interactive session, this line shows information for the snippet that defined the function—the 1 in "<ipython-input-1-7268c8ff93a9>" means snippet [1].

  • The type of the item for which you accessed IPython’s help mechanism—in this case, a function.

If the function’s source code is accessible from IPython—such as a function defined in the current session or imported into the session from a .py file—you can use ?? to display the function’s full source-code definition:

In [6]: square??
Signature: square(number)
Source:
def square(number):
    """Calculate the square of number."""
    return number ** 2
File:      ~/Documents/examples/ch04/<ipython-input-1-7268c8ff93a9>
Type:      function

If the source code is not accessible from IPython, ?? simply shows the docstring.

If the docstring fits in the window, IPython displays the next In [] prompt. If a docstring is too long to fit, IPython indicates that there’s more by displaying a colon (:) at the bottom of the window—press the Space key to display the next screen. You can navigate backwards and forwards through the docstring with the up and down arrow keys, respectively. IPython displays (END) at the end of the docstring. Press q (for “quit”) at any : or the (END) prompt to return to the next In [] prompt. To get a sense of IPython’s features, type ? at any In [] prompt, press Enter, then read the help documentation overview.

Self Check

  1. (True/False) The function body is referred to as its suite.
    Answer: False. The function body is referred to as its block.

  2. (True/False) A function’s local variables exist after the function returns to its caller.
    Answer: False. A function’s local variables exist until the function returns to its caller.

  3. (IPython Session) Define a function square_root that receives a number as a parameter and returns the square root of that number. Determine the square root of 6.25.
    Answer:

    In [1]: def square_root(number):
       ...:     return number ** 0.5 # or number ** (1 / 2)
       ...:
    
    In [2]: square_root(6.25)
    Out[2]: 2.5
    
..................Content has been hidden....................

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