ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ
Arguments in depth
In lesson 5.1 each argument went to the parameter in the same place. That's one of two ways Python matches them. By the end of this lesson you'll pass arguments by position or by name, give parameters default values, and avoid a default that quietly remembers every call.
Position decides
A taxi charges a starting fare plus 12 birr per kilometre (lesson 1.2). This version takes the distance first, then the starting fare. Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
def taxi_fare(km, base):
return base + km * 12
print(taxi_fare(10, 15))Python prints
135
The first argument goes to the first parameter, whatever the numbers look like. km is 10 and base is 15, so it's 15 + 10 * 12.
Python doesn't guess which number is which. A goes to the parameter in the same place, so swapping them changes the answer:
def taxi_fare(km, base):
return base + km * 12
print(taxi_fare(10, 15))
print(taxi_fare(15, 10))In the editor, press Escape then Tab to move on.
Arguments by name
You can also name the parameter in the call. A goes to the parameter with that name, so its place doesn't matter, and the call says what each number means:
def taxi_fare(km, base):
return base + km * 12
print(taxi_fare(base=15, km=10))
print(taxi_fare(10, base=15))In the editor, press Escape then Tab to move on.
The second call mixes both. That works when the positional arguments come first. The
other way round, Python can't tell which place 15 is meant for:
Every parameter needs exactly one value. Leave one out, or give one too many, and the error names the function and counts for you:
Default values
Most prices use the standard 15% VAT, so make that the rate unless the call says
otherwise. rate=0.15 in the def gives rate a
:
def vat(price, rate=0.15):
return price * (1 + rate)
print(vat(1000))
print(vat(1000, rate=0.05))In the editor, press Escape then Tab to move on.
The first call leaves rate out, so it's 0.15. The second passes 0.05 (an example
rate), which replaces the default for that call only. Parameters with defaults come
after the ones without.
A default that remembers
A default value is made once, when def runs, not at each call. For a number that
never matters, because a number can't change. For a list, it does. Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
def add(item, items=[]):
items.append(item)
return items
print(add(1))
print(add(2))Python prints
[1] [1, 2]
Both calls leave items out, so both get the same default list, made once when def ran. The first call appends 1 to it, and the second finds the 1 still there.
Step through it. The default list is kept with the function, so it's there before any call, and it stays after each call ends:
One default list for every call
Press Next to run one line at a time. Each arrow shows the object a name refers to. Each call gets its own frame of names, below the frame that called it.Each row is one step: the line that just ran, and the object each name refers to after it, frame by frame, oldest first.
Frames, oldest first: global. add's default list is []; no name refers to it.
Step 1 of 9
Step 1 of 9. Line 1: def add(item, items=[]):. Nothing in memory changed.
| Step | Line | Names and objects |
|---|---|---|
| 1 | 1 |
|
| 2 | 5 |
|
| 3 | 2 |
|
| 4 | 3 |
|
| 5 | 5 |
|
| 6 | 6 |
|
| 7 | 2 |
|
| 8 | 3 |
|
| 9 | 6 |
|
Both calls' items refer to one list, and so do first and second. That's lesson
4.8 again: one list with several names, so a change through one name shows through all
of them. The only surprise is when the list was made: once, when def ran. The fix is
to use None as the default and make a new list inside the call, which runs every time:
def add(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add(1))
print(add(2))In the editor, press Escape then Tab to move on.
Use None as the default for any list, dict, or set.
Two markers you'll see in documentation
Python's documentation writes sorted as sorted(iterable, /, *, key=None, reverse=False). The two markers are rules about how to pass arguments. Parameters
before a / must be positional: you can't write sorted(iterable=...). Parameters
after a * must be keyword arguments: reverse only works as reverse=True.
print(sorted([2, 3, 1], reverse=True))In the editor, press Escape then Tab to move on.
Your own functions can use them too. A / after price makes it positional only:
You won't need either marker for a long time, but now you can read them.
ጥያቄ
With def taxi_fare(km, base=50):, which call is an error?
መልመጃ
A fare with defaults
Write fare(km, base=20, per_km=5) returning base + km * per_km (example prices).
Call it three ways: 10 km with both defaults, 10 km with a base of 30, and 10 km at
8 birr per km, using a keyword argument so base keeps its default.
70
80
100Your code
# Define fare, then print three callsIn the editor, press Escape then Tab to move on.
መፍትሄውን አሳይHide the solution
This is one way to solve it, not the only one. If yours prints the same thing, it works.
def fare(km, base=20, per_km=5):
return base + km * per_km
print(fare(10))
print(fare(10, 30))
print(fare(10, per_km=8))ዋና ዋና ነጥቦች
- Positional arguments match parameters by place; keyword arguments (
base=15) match by name. - In a call, positional arguments come before keyword arguments.
- Missing or extra arguments raise a
TypeErrorthat names and counts them. - A default value (
rate=0.15) is used when the call leaves that argument out. - A default is made once, so never use a list as one: default to
Noneand make the list inside.