Functions, call frames and returned results
แนะนำใหม่| English | ความหมาย |
|---|---|
| function/ˈfʌŋkʃn/ | ฟังก์ชัน |
| side effect/saɪd ɪˈfekt/ | ผลข้างเคียง |
| contract/ˈkɒntrækt/ | สัญญา |
| parameter/pəˈræmɪtə/ | พารามิเตอร์ |
| argument/ˈɑːɡjuːmənt/ | อาร์กิวเมนต์ |
| call frame/kɔːl freɪm/ | เฟรมการเรียกใช้ |
| scope/skəʊp/ | สเปกตรัม |
| local variable/ˈləʊkl ˈveərɪəbl/ | ตัวแปรท้องถิ่น |
| decomposition/ˌdiːkɒmpəˈzɪʃn/ | การแยกย่อย |
Give each function one clear job
- A function 函数 groups a named task. State its inputs, its returned result and any side effect 副作用, such as printing, before writing the body.
- A contract 契约 says what callers may supply and what the function promises. Here, amounts are whole pence and must be non-negative integers.
def add_fee(amount):
"""Return amount plus a fixed fee of 3 pence."""
return amount + 3
add_fee(8) evaluates to 11. It does not print anything. Keeping calculation separate from display lets another function reuse the result.
Which contract lets another calculation use the fee-inclusive amount directly?
ความยาก 1/5 · 100 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
A returned result can be used in an expression; printed output is a separate side effect.
Distinguish the input name from the input object
- In a definition,
amountis a parameter 形参. Inadd_fee(8), the expression8supplies an argument 实参. Argument expressions are evaluated before the function body runs. - The call binds the parameter name to the supplied object. It does not automatically copy that object or create a link between the caller's name and the parameter's name.
amount = 4
result = add_fee(amount * 2)
print(amount, result)
The argument expression gives 8; inside the call, amount refers to that integer. The returned 11 becomes result. The module's amount still refers to 4, so the output is 4 11.
Match each term to its role in add_fee(8).
ความยาก 2/5 · 140 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
The argument is evaluated at the call; its object is bound to the parameter; return hands a result back.
Keep a separate frame for each call
- A call frame 调用帧 records one active function call, including its parameters and local names. When one function calls another, the caller waits for the returned value.
- Read this program in execution order: module →
twice→add_fee→twice→ module. The arrows below are conceptual control flow, not a physical memory layout.
def twice(amount):
subtotal = amount * 2
return add_fee(subtotal)
amount = 4
result = twice(amount)
print(amount, result)

Use the trace to inspect the calls and returns. The frame details show the state at the nested call. It is an authored trace of this exact example, not a Python interpreter.
Trace twice(4) calling add_fee(8)
Separate local bindings from returned values.
Put these events in the order followed by result = twice(4).
ความยาก 3/5 · 200 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
The nested call finishes before twice can finish its return expression.
What integer is bound to amount inside add_fee during this nested call?
ความยาก 2/5 · 140 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
twice calculates subtotal as 4 times 2, then passes that 8 to add_fee.
Return a result; print a message
returnends the current call and gives an object back to the caller. A function that reaches its end withoutreturngivesNone.printwrites output. It also returnsNone, so printing a calculation inside a function does not make that calculation its returned result.
def show_fee(amount):
print(amount + 3)
value = show_fee(8)
print(value)
This prints 11, then None, on separate lines. If the caller needs the number, use return amount + 3 and let the caller decide whether to print it.
show_fee prints 11 but has no return statement. What is stored in value?
ความยาก 1/5 · 100 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
Falling off the end of a Python function returns None, regardless of printed output.
Resolve names in the right scope
- A local variable 局部变量 belongs to a function call. Its scope 作用域 determines where a name can be resolved; another function does not receive access to the caller's local names automatically.
- Assigning a parameter a new integer changes its local binding. It does not reassign a same-named variable in the caller.
def increase(amount):
amount = amount + 1
return amount
amount = 4
new_amount = increase(amount)
print(amount, new_amount)
The output is 4 5. Both names begin by referring to the integer 4; the assignment inside the function rebinds its local name. To update the module name, write amount = increase(amount).
After new_amount = increase(amount), what value does the module's amount still hold?
ความยาก 2/5 · 140 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
Only the function's local name was rebound; the caller did not assign to amount.
Decompose a calculation into testable pieces
- Decomposition 分解 separates a larger task into smaller jobs with clear contracts. For an order, calculate an item subtotal, add a fee, then display the final amount.
- Test calculations directly, including zero quantity and more than one item. State that inputs are non-negative integers; input validation can be a separate function.
def item_subtotal(unit_pence, quantity):
return unit_pence * quantity
def order_total(unit_pence, quantity):
return add_fee(item_subtotal(unit_pence, quantity))
order_total(5, 2) gives 13; order_total(5, 0) gives 3 under this fixed-fee contract. If zero-item orders should cost zero, change the contract and implementation together.
Under the stated fixed-fee contract, what does order_total(5, 0) return in pence?
ความยาก 2/5 · 140 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
The item subtotal is zero, but add_fee still adds 3. Free empty orders require a different contract.
Explain the whole call before trusting the answer
- Trace the argument expressions, parameter bindings, local calculations and returned values. Check the caller's state after the call and the output separately.
- Do not describe parameter passing as copying every object. A mutable collection can be changed through a parameter; object diagrams for mutation and aliasing follow in unit 1.5.
A correct printed number does not prove a correct returned result. Use direct checks such as assert order_total(5, 2) == 13, then inspect any expected output separately.
Language references: Python functions and name binding and scope.
Calling a Python function automatically copies every argument object.
ความยาก 1/5 · 100 เหรียญ + บอนัสน้อยๆ เมื่อทำสำเร็จครั้งแรกในวันนี้
Parameters are bound to supplied objects. Copying must be requested explicitly when needed.