An object is any value in Python: a number, a list, a dict. A function is an object too. You can put it in a list, pass it to another function, or store it in a dict.
A function in a listworked example
orders = [
{"order_id": 101, "status": "paid", "amount": 40.0},
# ... orders 102 to 106 ...
]
def paid_total(orders):
return sum(o["amount"] for o in orders if o["status"] == "paid")
steps = [paid_total]
print(steps[0](orders), paid_total.__name__)
steps[0] is the function itself, and (orders) calls it. Every function knows its own name, in __name__.
A dict of functions can choose what to do for each value. This replaces a long chain of if and elif:
A dict of handlersworked example
def on_paid(order): return f"book {order['amount']}"
def on_refunded(order): return f"reverse {order['amount']}"
def on_pending(order): return "wait"
handlers = {"paid": on_paid, "refunded": on_refunded, "pending": on_pending}
for order in orders[2:5]:
print(order["order_id"], handlers[order["status"]](order))
Result · 3 rows
| output |
|---|
| 103 reverse 60.0 |
| 104 book 15.5 |
| 105 wait |
Write on_paid without (), so the dict stores the function. With (), it would store a result.
A function inside a function
A function can create and return another function. The inner function keeps the names of the outer one. This is called a closure:
A counter that remembersworked example
def make_counter():
count = 0
def add():
nonlocal count
count += 1
return count
return add
a = make_counter()
b = make_counter()
print(a(), a(), b())
nonlocal lets add() change count of the outer function. Each call to make_counter makes a new count.
A closure keeps the name, not the value it had. Functions built in a loop all see the last value of the loop:
Checks built in a loopworked example
checks = [lambda value: value > limit for limit in [10, 50]]
print([check(30) for check in checks])
checks = [lambda value, limit=limit: value > limit for limit in [10, 50]]
print([check(30) for check in checks])
Result · 2 rows
| output |
|---|
| [False, False] |
| [True, False] |
A lambda is a short function written on one line. In the first list, both checks use limit 50. A default value (limit=limit) keeps each value.
The second list works because a default value is saved when the function is created (chapter 6).