# Kazi katika Python: def, return, hoja, *args na **kwargs, lambda na type hints

URL: https://skillaria.top/sw/guides/python/funkcii-python

Kazi katika Python ni kizuizi chenye jina kinachotangazwa kwa neno def, kinaitwa kwa jina pamoja na mabano, na kurudisha matokeo kwa return; bila return kazi hurudisha None. Hoja hupitishwa kwa mpangilio au kwa jina, *args hukusanya hoja za ziada za nafasi kuwa tuple, **kwargs hukusanya zile zilizotajwa kwa jina kuwa kamusi, na lambda huunda kazi fupi isiyo na jina kutoka kwa usemi mmoja.

Kazi katika Python ni kipande cha msimbo chenye jina ambacho kinaweza kuitwa mara nyingi upendavyo kwa data tofauti za kuingiza. Hutangazwa kwa neno `def`, hupokea thamani kupitia vigezo, na hutoa matokeo kwa `return`. Kazi ndiyo njia kuu ya kugeuza hati ndefu kuwa hatua zilizo wazi na zinazoweza kukaguliwa.

## Jinsi ya kutangaza kazi: def python

Tangazo la kazi huanza kwa `def`, kisha jina, vigezo kwenye mabano na koloni. Mwili wa kazi huandikwa kwa ujongezaji wa nafasi nne — ujongezaji katika Python si pambo, bali ni sehemu ya sintaksia.

```
def greet(name):
    """Inarudisha salamu kwa mtumiaji."""
    return f"Habari, {name}!"

print(greet("Amina"))   # Habari, Amina!
```

Mfuatano wa nukuu tatu mara baada ya kichwa cha kazi ni docstring, yaani nyaraka za kazi. `help(greet)` na vidokezo vya mhariri huionyesha. Majina ya kazi kwa mujibu wa PEP 8 huandikwa kwa snake_case: `add_expense`, `get_rate`.

Mstari `def greet(name):` huitwa sahihi ya kazi (signature): jina pamoja na orodha ya vigezo (na type hints, ikiwa zipo). Kwa sahihi msomaji anaelewa jinsi ya kuitumia bila kuangalia mwili wake.

## Kazi ya return katika Python

`return` humaliza kazi na kumpa aliyeiita thamani. Msimbo uliopo baada ya `return` iliyotekelezwa haufanyiki. Ikiwa `return` haipo, au imeandikwa bila thamani, kazi inarudisha `None`.

```
def area(w, h):
    w * h          # hesabu imefanyika lakini imetupwa

print(area(3, 4))  # None

def area(w, h):
    return w * h

print(area(3, 4))  # 12
```

Kusahau `return` ni mojawapo ya makosa ya kawaida ya wanaoanza: kazi "inafanya kazi", lakini inarudisha `None`, na kosa linajitokeza mstari mmoja baadaye. Kazi inaweza kurudisha thamani kadhaa — kwa kweli ni tuple moja, ambayo ni rahisi kuifungua:

```
def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([4, 1, 9])
print(low, high)   # 1 9
```

Return ya mapema husaidia kuepuka ujongezaji usio wa lazima: kwanza kushughulikia visa maalum, kisha kuandika mantiki kuu.

```
def discount(price, is_member):
    if price  limit    # kusoma kigezo cha kimataifa — kunaruhusiwa

def raise_limit():
    global limit
    limit = 2000             # bila global, ingeundwa kigezo cha ndani
```

Kwa vitendo, `global` ni bora kuepukwa: kazi inayobadilisha hali ya nje ni ngumu kupima. Ni bora kupokea thamani kama hoja na kurudisha matokeo.

## Kazi zilizoingiana na funga (closures)

Kazi inaweza kutangazwa ndani ya kazi nyingine. Kazi iliyoingizwa huona vigezo vya nje hata baada ya ile ya nje kumaliza — hiyo ndiyo closure. Ili kubadilisha kigezo kama hicho hutumika `nonlocal`.

```
def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

c = make_counter()
print(c(), c(), c())   # 1 2 3
```

Closures ndizo msingi wa decorators na viwanda vya kazi (function factories).

## Kazi pia ni kitu

Katika Python kazi ni kitu cha kawaida: unaweza kuiweka kwenye kigezo, kuipitisha kwa kazi nyingine, kuirudisha kutoka kazini, au kuihifadhi kwenye kamusi. Ina sifa: `__name__`, `__doc__`, `__defaults__`, `__annotations__`.

```
def double(x):
    return x * 2

f = double
print(f(5), f.__name__)                # 10 double
print(list(map(double, [1, 2, 3])))   # [2, 4, 6]
```

## Lambda katika Python: kazi zisizo na jina

Lambda ni kazi fupi isiyo na jina ambayo mwili wake ni usemi mmoja. Matokeo ya usemi hurudishwa moja kwa moja, na `return` haitumiki.

```
square = lambda x: x ** 2
print(square(4))   # 16

expenses = [("Kahawa", 250), ("Teksi", 600), ("Chakula", 450)]
expenses.sort(key=lambda e: e[1], reverse=True)
print(expenses)  # [('Teksi', 600), ('Chakula', 450), ('Kahawa', 250)]

print(list(filter(lambda n: n % 2 == 0, range(10))))  # [0, 2, 4, 6, 8]
```

Lambda inafaa kama hoja fupi ya `sorted`, `max`, `map`, `filter`. Kuweka lambda kwenye kigezo, kama `square` hapo juu, PEP 8 haipendekezi: kazi ikihitaji jina, andika `def` — itakuwa na `__name__` sahihi kwenye traceback na mahali pa docstring.

|  | def | lambda |
| --- | --- | --- |

| Jina | lipo | halipo (`<lambda>`) |

| Mwili | idadi yoyote ya amri | usemi mmoja |

| return | wazi | kimyakimya |

| Docstring, type hints | ndiyo | hapana |

| Inafaa wapi | kila mahali | key fupi au callback |

## Type hints: vidokezo, si ukaguzi

Type hints zinaeleza aina zinazotarajiwa za vigezo na matokeo. Python yenyewe haizikagui wakati wa kuendesha: kazi yenye `x: int` itapokea mfuatano bila tatizo. Ukaguzi unafanywa na zana za nje — mypy, pyright, ty — na mhariri anayeonyesha kosa kabla ya kuendesha.

```
def add_expense(title: str, amount: float, category: str = "nyingine") -> dict[str, object]:
    return {"title": title, "amount": amount, "category": category}

def area(w: float, h: float) -> float:
    w * h   # mypy: Missing return statement
```

Ukaguzi unaweza kuendeshwa bila kusakinisha kwa `uvx mypy .`. Mfano hapo juu unaonyesha faida ya type hints: return iliyosahauliwa kwa `-> float` inanaswa mara moja na kichambuzi.

Kuanzia Python 3.12 (PEP 695) kazi za jumla huandikwa bila `TypeVar`: kigezo cha aina kinaandikwa kwenye mabano ya mraba, na jina bandia la aina linatangazwa kwa neno `type`.

```
def first[T](xs: list[T]) -> T:
    return xs[0]

type Money = int | float
```

Katika Python 3.14 (PEP 649) type hints zikawa za uvivu: zinakokotolewa wakati zinapotumika kwa mara ya kwanza, kwa hiyo unaweza kurejelea darasa lililotangazwa chini bila nukuu, na `from __future__ import annotations` haihitajiki tena.

## "Hakupitishwa" au "amepitisha None": sentinel katika 3.15

Thamani `None` kama chaguo-msingi haiwezi kutofautisha "hoja haikupitishwa" na "None imepitishwa kwa makusudi". Kwa miaka watu walitatua hili kwa kiashiria cha kujitengenezea:

```
_MISSING = object()

def get_rate(currency, default=_MISSING):
    rates = {"USD": 90.5}
    if currency in rates:
        return rates[currency]
    if default is _MISSING:
        raise KeyError(currency)
    return default
```

Katika Python 3.15 kuna kazi iliyojengwa ndani `sentinel` (PEP 661): `MISSING = sentinel("MISSING")` huunda alama ya kipekee yenye repr inayoeleweka, ambayo wakati wa kunakili inabaki yenyewe, inahifadhiwa kwa pickle, na inafaa kwa type hint kama `float | MISSING`. Kwenye matoleo ya zamani mbinu ya `object()` inaendelea kufanya kazi.

## Makosa ya kawaida na kazi

- **Umesahau return** — kazi inarudisha `None`.
- **Umesahau mabano** — `print(greet)` itachapisha kitu cha kazi, si matokeo ya wito.
- **Thamani chaguo-msingi inayoweza kubadilika** — orodha moja ya pamoja kwa miito yote.
- **Idadi isiyo sahihi ya hoja** — `TypeError: greet() missing 1 required positional argument: 'name'`.
- **Jina sawa na kazi iliyojengwa ndani** — kazi yako inayoitwa `list` au `sum` itaficha ile iliyojengwa ndani.

## Hitimisho

Kazi katika Python zinatangazwa kwa `def`, zinarudisha matokeo kwa `return`, na zinapokea hoja kwa mpangilio au kwa jina. `*args` na `**kwargs` zinatoa unyumbufu, `/` na `*` zinatoa ukali wa wito, lambda ni fupi kwa kazi ya mara moja, na type hints pamoja na mypy zinanasa makosa kabla ya kuendesha. Katika kozi ya Python mada hii inafundishwa kwa vitendo: kifuatiliaji cha matumizi kinagawanywa kuwa kazi zenye type hints na kukaguliwa kwa mypy.

## FAQ

**Kigezo kinatofautianaje na hoja?**

Kigezo ni jina lililoandikwa kwenye tangazo la kazi, hoja ni thamani halisi inayopitishwa wakati wa wito. Katika def greet(name) name ni kigezo, na katika greet("Amina") mfuatano "Amina" ni hoja.

**Je, naweza kuita kazi kabla ya kutangazwa?**

Kwenye kiwango cha moduli hapana: mstari wa def lazima utekelezwe kabla ya wito, vinginevyo utapata NameError. Lakini ndani ya kazi nyingine unaweza kuita kazi iliyotangazwa chini, mradi wito utokee baada ya tangazo lake.

**Kazi inaweza kurudisha thamani ngapi?**

Kiufundi moja, lakini thamani hiyo inaweza kuwa tuple: return a, b inarudisha tuple ya vipengele viwili, ambayo hufunguliwa kama x, y = f().

**Je, ni lazima kuandika type hints?**

Hapana, Python inafanya kazi bila hizo. Lakini kwenye msimbo ambao watu wengine wanausoma, type hints zinarahisisha matengenezo na kuruhusu mypy au pyright kupata makosa kabla ya kuendesha.

**Je, naweza kuandika if ndani ya lambda?**

Unaweza kutumia usemi wa masharti tu: lambda x: "sawa" if x % 2 == 0 else "isiyo sawa". Amri, mizunguko na mgawo ndani ya lambda haviruhusiwi.


---
Source: Skillaria.Top (https://skillaria.top)
