Skip to content

Latest commit

 

History

History
146 lines (109 loc) · 3 KB

File metadata and controls

146 lines (109 loc) · 3 KB

+++ slug = "functions" title = "Functions" section = "Functions" summary = "Use def to name reusable behavior and return results." doc_path = "/tutorial/controlflow.html#defining-functions" see_also = [ "variables", "args-and-kwargs", "keyword-only-arguments", "closures", ] +++

Functions package behavior behind a name. def creates a function object that can accept arguments, compute values, and return a result.

Default arguments make common calls short, and keyword arguments make call sites easier to read. A function that reaches the end without return produces None.

Use functions when a calculation has a useful name, when code repeats, or when a piece of behavior should be tested independently.

:::program

def greet(name):
    return f"Hello, {name}."

print(greet("Python"))


def format_total(amount, currency="USD"):
    return f"{amount} {currency}"

print(format_total(10))
print(format_total(10, currency="EUR"))


def log(message):
    print(f"log: {message}")

result = log("saved")
print(result)


def append_broken(item, items=[]):
    items.append(item)
    return items

print(append_broken("a"))
print(append_broken("b"))


def append_fixed(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(append_fixed("a"))
print(append_fixed("b"))

:::

:::cell return sends a value back to the caller. The caller can print it, store it, or pass it to another function.

def greet(name):
    return f"Hello, {name}."

print(greet("Python"))
Hello, Python.

:::

:::cell Default arguments provide common values. Keyword arguments make it clear which option is being overridden.

def format_total(amount, currency="USD"):
    return f"{amount} {currency}"

print(format_total(10))
print(format_total(10, currency="EUR"))
10 USD
10 EUR

:::

:::cell A function without an explicit return returns None. That makes side-effect-only functions easy to distinguish from value-producing ones.

def log(message):
    print(f"log: {message}")

result = log("saved")
print(result)
log: saved
None

:::

:::cell Mutable default arguments are evaluated once when the function is defined, not on each call. The same list is shared across calls, so successive calls see each other's mutations. Use None as the sentinel and create a fresh container inside the body.

def append_broken(item, items=[]):
    items.append(item)
    return items

print(append_broken("a"))
print(append_broken("b"))


def append_fixed(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(append_fixed("a"))
print(append_fixed("b"))
['a']
['a', 'b']
['a']
['b']

:::

:::note

  • Use return for values the caller should receive.
  • Defaults keep common calls concise.
  • Keyword arguments make options readable at the call site.
  • Never use a mutable value as a default argument; use None and build the container inside the function body. :::