6. Funksiyalar

Funksiya — ma’lum bir vazifani bajaradigan, nom berilgan va kerak bo‘lganda qayta chaqirilishi mumkin bo‘lgan kod qismidir.

Masalan, bir xil salomlashish kodini bir necha marta yozish o‘rniga funksiya yaratamiz:

def salomlash():

    print(
        "Salom, Softromeda!"
    )

Funksiyani chaqirish:

salomlash()

Natija:

Salom, Softromeda!

Funksiya nima uchun kerak?

Funksiyalar quyidagi muammolarni hal qiladi:

Kod takrorlanishini kamaytirish
Kodni tartibli saqlash
Murakkab vazifalarni kichik qismlarga ajratish
Koddan qayta foydalanish
Dastur tuzilishini yaxshilash

Masalan, funksiyasiz:

ism = "Softromeda"

print(
    f"Salom, {ism}!"
)

ism = "Ali"

print(
    f"Salom, {ism}!"
)

Funksiya bilan:

def salomlash(ism):

    print(
        f"Salom, {ism}!"
    )


salomlash("Softromeda")
salomlash("Ali")

Funksiya yaratish

Python'da funksiya def kalit so‘zi bilan yaratiladi.

def salomlash():

    print(
        "Salom!"
    )

Umumiy ko‘rinishi:

def funksiya_nomi():

    bajariladigan_kod

Funksiya o‘z-o‘zidan ishlamaydi.

Uni chaqirish kerak:

salomlash()

Funksiya nomlash

Funksiya nomlari odatda snake_case uslubida yoziladi:

def foydalanuvchini_tekshirish():

    pass
def hisoblash():

    pass
def ma_lumot_olish():

    pass

Funksiya nomi uning nima ish qilishini ifodalashi yaxshi.


Parametrlar

Funksiyaga tashqaridan ma’lumot berish uchun parametrlar ishlatiladi.

def salomlash(ism):

    print(
        f"Salom, {ism}!"
    )

Chaqirish:

salomlash(
    "Softromeda"
)

Natija:

Salom, Softromeda!

Bu yerda ism parametr hisoblanadi.


Bir nechta parametr

Funksiya bir nechta parametr qabul qilishi mumkin.

def foydalanuvchi_ma_lumoti(
    ism,
    yosh
):

    print(
        f"Ism: {ism}"
    )

    print(
        f"Yosh: {yosh}"
    )

Chaqirish:

foydalanuvchi_ma_lumoti(
    "Softromeda",
    25
)

Natija:

Ism: Softromeda
Yosh: 25

Argument va parametr

Quyidagi funksiya:

def salomlash(ism):

    print(
        f"Salom, {ism}!"
    )

Bu yerda:

ism → parametr

Funksiyani chaqirganda:

salomlash(
    "Softromeda"
)

bu yerda:

"Softromeda" → argument

return

Funksiya natijani tashqariga qaytarishi uchun return ishlatiladi.

def qoshish(
    birinchi_son,
    ikkinchi_son
):

    natija = (
        birinchi_son
        + ikkinchi_son
    )

    return natija

Natijani olish:

yigindi = qoshish(
    10,
    20
)

print(
    f"Yig‘indi: {yigindi}"
)

Natija:

Yig‘indi: 30

return va print farqi

print() qiymatni ekranga chiqaradi.

return esa qiymatni funksiya chaqirilgan joyga qaytaradi.

Masalan:

def print_yigindi(
    birinchi_son,
    ikkinchi_son
):

    print(
        birinchi_son
        + ikkinchi_son
    )

Bu funksiya faqat chiqaradi.

Boshqa funksiya:

def hisobla(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        + ikkinchi_son
    )

Natijani o‘zgaruvchiga saqlash mumkin:

natija = hisobla(
    10,
    20
)

returndan keyingi kod

return bajarilgandan keyin funksiya darhol tugaydi.

def tekshir():

    print(
        "Birinchi xabar."
    )

    return

    print(
        "Ikkinchi xabar."
    )

Natija:

Birinchi xabar.

Ikkinchi print() bajarilmaydi.


Bir nechta qiymat qaytarish

Python'da funksiya bir nechta qiymatni tuple sifatida qaytarishi mumkin.

def hisobla(
    birinchi_son,
    ikkinchi_son
):

    yigindi = (
        birinchi_son
        + ikkinchi_son
    )

    ayirma = (
        birinchi_son
        - ikkinchi_son
    )

    return (
        yigindi,
        ayirma
    )

Qabul qilish:

yigindi, ayirma = hisobla(
    20,
    5
)

print(
    f"Yig‘indi: {yigindi}"
)

print(
    f"Ayirma: {ayirma}"
)

Natija:

Yig‘indi: 25
Ayirma: 15

Standart parametr

Funksiyaga standart qiymat berish mumkin.

def salomlash(
    ism="Softromeda"
):

    print(
        f"Salom, {ism}!"
    )

Argument bermasak:

salomlash()

Natija:

Salom, Softromeda!

Boshqa qiymat bersak:

salomlash(
    "Ali"
)

Natija:

Salom, Ali!

Nomlangan argumentlar

Argumentlarni nomi bilan berish mumkin.

def foydalanuvchi_ma_lumoti(
    ism,
    yosh,
    kasb
):

    print(
        f"{ism}, {yosh} yosh, {kasb}."
    )

Chaqirish:

foydalanuvchi_ma_lumoti(
    yosh=25,
    kasb="Dasturchi",
    ism="Softromeda"
)

Bu usul argumentlar tartibini aniq ko‘rsatadi.


Aralash argumentlar

Oddiy va nomlangan argumentlarni birga ishlatish mumkin.

def foydalanuvchi_ma_lumoti(
    ism,
    yosh,
    kasb
):

    print(
        f"Ism: {ism}"
    )

    print(
        f"Yosh: {yosh}"
    )

    print(
        f"Kasb: {kasb}"
    )


foydalanuvchi_ma_lumoti(
    "Softromeda",
    kasb="Dasturchi",
    yosh=25
)

Muhim qoida:

Oddiy argumentlar
→ nomlangan argumentlardan oldin keladi.

*args

Funksiya noma’lum miqdordagi pozitsion argumentlarni qabul qilishi mumkin.

def yigindi_hisobla(*sonlar):

    yigindi = 0

    for son in sonlar:

        yigindi += son

    return yigindi

Chaqirish:

natija = yigindi_hisobla(
    10,
    20,
    30,
    40
)

print(
    f"Yig‘indi: {natija}"
)

Natija:

Yig‘indi: 100

sonlar ichida tuple hosil bo‘ladi.


**kwargs

Noma’lum miqdordagi nomlangan argumentlarni qabul qilish uchun **kwargs ishlatiladi.

def foydalanuvchi_ma_lumoti(
    **ma_lumotlar
):

    for kalit, qiymat in ma_lumotlar.items():

        print(
            f"{kalit}: {qiymat}"
        )

Chaqirish:

foydalanuvchi_ma_lumoti(
    ism="Softromeda",
    yosh=25,
    kasb="Dasturchi"
)

Natija:

ism: Softromeda
yosh: 25
kasb: Dasturchi

ma_lumotlar dictionary bo‘ladi.


*args va **kwargs birgalikda

def ma_lumotlarni_chiqar(
    *ismlar,
    **ma_lumotlar
):

    for ism in ismlar:

        print(
            f"Ism: {ism}"
        )

    for kalit, qiymat in ma_lumotlar.items():

        print(
            f"{kalit}: {qiymat}"
        )

Chaqirish:

ma_lumotlarni_chiqar(
    "Softromeda",
    "Ali",
    yosh=25,
    kasb="Dasturchi"
)

Funksiya ichidagi o‘zgaruvchi

Funksiya ichida yaratilgan o‘zgaruvchi odatda lokal o‘zgaruvchi hisoblanadi.

def hisobla():

    natija = 10 + 20

    print(
        natija
    )


hisobla()

natija funksiyadan tashqarida mavjud emas.

def hisobla():

    natija = 30


hisobla()

print(
    natija
)

Bu kod xatolik beradi.


Global o‘zgaruvchi

Funksiya tashqarisida yaratilgan o‘zgaruvchi global scope'da bo‘ladi.

ism = "Softromeda"

def salomlash():

    print(
        f"Salom, {ism}!"
    )


salomlash()

Funksiya tashqarisidagi ism funksiyadan o‘qilishi mumkin.

Lekin katta dasturlarda global o‘zgaruvchilardan haddan tashqari foydalanish tavsiya etilmaydi.


global

Global o‘zgaruvchini funksiya ichida o‘zgartirish uchun global ishlatilishi mumkin.

hisoblagich = 0

def oshir():

    global hisoblagich

    hisoblagich += 1


oshir()
oshir()

print(
    hisoblagich
)

Natija:

2

Ammo ko‘pincha bunday kod o‘rniga qiymatni parametr va return orqali boshqarish yaxshiroq:

def oshir(
    qiymat
):

    return qiymat + 1


hisoblagich = 0

hisoblagich = oshir(
    hisoblagich
)

hisoblagich = oshir(
    hisoblagich
)

print(
    hisoblagich
)

Funksiyalarni kichik vazifalarga ajratish

Katta funksiyadan ko‘ra kichik va aniq vazifali funksiyalar ko‘pincha qulayroq.

Masalan:

def sonni_tekshir(
    son
):

    return son % 2 == 0


def natijani_chiqar(
    son
):

    if sonni_tekshir(son):

        print(
            "Son juft."
        )

    else:

        print(
            "Son toq."
        )


natijani_chiqar(
    10
)

Funksiya ichida sikl

Funksiya ichida sikl ishlatish mumkin.

def sonlarni_chiqar(
    boshlanish,
    tugash
):

    for son in range(
        boshlanish,
        tugash + 1
    ):

        print(
            son
        )


sonlarni_chiqar(
    1,
    5
)

Natija:

1
2
3
4
5

Funksiya ichida shart

def bahoni_aniqla(
    ball
):

    if ball >= 90:

        return "A'lo"

    elif ball >= 70:

        return "Yaxshi"

    elif ball >= 60:

        return "Qoniqarli"

    else:

        return "Qoniqarsiz"

Foydalanish:

natija = bahoni_aniqla(
    85
)

print(
    f"Natija: {natija}"
)

Natija:

Natija: Yaxshi

Funksiyani boshqa funksiya ichidan chaqirish

Funksiyalar bir-birini chaqirishi mumkin.

def yigindi_hisobla(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        + ikkinchi_son
    )


def natijani_chiqar(
    birinchi_son,
    ikkinchi_son
):

    natija = yigindi_hisobla(
        birinchi_son,
        ikkinchi_son
    )

    print(
        f"Yig‘indi: {natija}"
    )


natijani_chiqar(
    10,
    20
)

Rekursiya

Funksiya o‘zini o‘zi chaqirishi mumkin.

Bunga rekursiya deyiladi.

Oddiy misol:

def sanash(
    son
):

    if son == 0:

        return

    print(
        son
    )

    sanash(
        son - 1
    )


sanash(
    5
)

Natija:

5
4
3
2
1

Rekursiyada albatta tugash sharti bo‘lishi kerak.

if son == 0:

    return

Aks holda funksiya cheksiz chaqirilishi mumkin.


Docstring

Funksiyaning nima qilishini tushuntirish uchun docstring yozish mumkin.

def qoshish(
    birinchi_son,
    ikkinchi_son
):
    """
    Ikki sonni qo‘shib,
    natijani qaytaradi.
    """

    return (
        birinchi_son
        + ikkinchi_son
    )

Docstring funksiyaning hujjatlashtirilishini yaxshilaydi.


Type hint

Funksiya parametrlarining kutilayotgan turini ko‘rsatish mumkin.

def qoshish(
    birinchi_son: int,
    ikkinchi_son: int
) -> int:

    return (
        birinchi_son
        + ikkinchi_son
    )

Bu Python'ni majburlab tekshirtirmaydi, lekin kodni o‘qishni va statik tahlil vositalaridan foydalanishni osonlashtiradi.


None qaytaradigan funksiya

Agar funksiya return bilan qiymat qaytarmasa, u None qaytaradi.

def salomlash():

    print(
        "Salom, Softromeda!"
    )


natija = salomlash()

print(
    natija
)

Natija:

Salom, Softromeda!
None

Lambda

Oddiy funksiyalarni qisqa ko‘rinishda lambda yordamida yozish mumkin.

kvadrat = lambda son: son ** 2

print(
    kvadrat(5)
)

Natija:

25

Lambda odatda juda kichik va oddiy funksiyalar uchun ishlatiladi.

Oddiy def esa murakkabroq vazifalar uchun ancha tushunarli.


Funksiyaga list uzatish

def royxatni_chiqar(
    mevalar
):

    for meva in mevalar:

        print(
            meva
        )


mevalar = [
    "olma",
    "banan",
    "anor"
]

royxatni_chiqar(
    mevalar
)

Funksiya orqali listni qayta ishlash

def juft_sonlarni_ol(
    sonlar
):

    natija = []

    for son in sonlar:

        if son % 2 == 0:

            natija.append(
                son
            )

    return natija


sonlar = [
    1,
    2,
    3,
    4,
    5,
    6
]

juft_sonlar = juft_sonlarni_ol(
    sonlar
)

print(
    juft_sonlar
)

Natija:

[2, 4, 6]

Funksiya orqali dictionary qayta ishlash

def foydalanuvchini_chiqar(
    foydalanuvchi
):

    print(
        f"Ism: {foydalanuvchi['ism']}"
    )

    print(
        f"Yosh: {foydalanuvchi['yosh']}"
    )

    print(
        f"Kasb: {foydalanuvchi['kasb']}"
    )


foydalanuvchi = {
    "ism": "Softromeda",
    "yosh": 25,
    "kasb": "Dasturchi"
}

foydalanuvchini_chiqar(
    foydalanuvchi
)

Funksiya dizayni

Yaxshi funksiya odatda:

Bitta aniq vazifani bajaradi
Tushunarli nomga ega
Kerakli parametrlarni qabul qiladi
Kerakli natijani qaytaradi
Yon ta’sirlari imkon qadar kam bo‘ladi

Masalan:

def kvadratni_hisobla(
    son
):

    return son ** 2

Bu funksiya juda aniq vazifaga ega.


Yomon va yaxshi funksiya

Yomonroq:

def ish():

    print("Softromeda")
    son = 10
    natija = son ** 2
    print(natija)
    # yana ko‘plab ishlar...

Yaxshiroq:

def kvadratni_hisobla(
    son
):

    return son ** 2


def foydalanuvchi_bilan_salamlash():

    print(
        "Salom, Softromeda!"
    )

Har bir funksiya alohida vazifani bajaradi.


Amaliy mashqlar

Mashq 1

Ikki sonni qabul qilib, ularning yig‘indisini qaytaradigan funksiya yozing.

Mashq 2

Sonning juft yoki toq ekanini aniqlaydigan funksiya yozing.

Mashq 3

Uchta sonning eng kattasini qaytaradigan funksiya yozing.

Mashq 4

Listdagi sonlar yig‘indisini qaytaradigan funksiya yozing.

Mashq 5

Listdagi eng katta sonni qaytaradigan funksiya yozing.

Mashq 6

Matnni qabul qilib, uning uzunligini qaytaradigan funksiya yozing.

Mashq 7

Foydalanuvchi yoshini qabul qilib, uning toifasini qaytaradigan funksiya yozing.

Mashq 8

*args yordamida istalgan miqdordagi sonlarning yig‘indisini hisoblang.

Mashq 9

**kwargs yordamida foydalanuvchi ma’lumotlarini qabul qiladigan funksiya yozing.

Mashq 10

Rekursiya yordamida 10 dan 1 gacha sanaydigan funksiya yozing.


Mini loyiha — Softromeda kalkulyatori

Bir nechta matematik amalni alohida funksiyalarga ajratamiz:

def qoshish(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        + ikkinchi_son
    )


def ayirish(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        - ikkinchi_son
    )


def kopaytirish(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        * ikkinchi_son
    )


def bolish(
    birinchi_son,
    ikkinchi_son
):

    if ikkinchi_son == 0:

        return None

    return (
        birinchi_son
        / ikkinchi_son
    )


birinchi_son = float(
    input(
        "Birinchi sonni kiriting: "
    )
)

ikkinchi_son = float(
    input(
        "Ikkinchi sonni kiriting: "
    )
)

print(
    f"Yig‘indi: {qoshish(birinchi_son, ikkinchi_son)}"
)

print(
    f"Ayirma: {ayirish(birinchi_son, ikkinchi_son)}"
)

print(
    f"Ko‘paytma: {kopaytirish(birinchi_son, ikkinchi_son)}"
)

natija = bolish(
    birinchi_son,
    ikkinchi_son
)

if natija is None:

    print(
        "Nolga bo‘lish mumkin emas."
    )

else:

    print(
        f"Bo‘linma: {natija}"
    )

Bu loyiha kodni funksiyalarga ajratishning amaliy foydasini ko‘rsatadi.


Bob xulosasi

Bu bobda funksiyalar bilan ishlashni o‘rgandik.

Asosiy tushunchalar:

def
parametr
argument
return
standart parametr
nomlangan argument
*args
**kwargs
lokal o‘zgaruvchi
global o‘zgaruvchi
rekursiya
docstring
type hint
lambda

Funksiyalar katta dasturlarni kichik, boshqariladigan qismlarga ajratishga yordam beradi.

Masalan:

def qoshish(
    birinchi_son,
    ikkinchi_son
):

    return (
        birinchi_son
        + ikkinchi_son
    )

Keyingi bobda stringlar bilan chuqurroq ishlash: slicing, metodlar, formatlash va matnni qayta ishlashni o‘rganamiz.