Python - Penjana: Pengenalan Lembut untuk Pemula

Hai di sana, yang berhasrat menjadi pengaturcara Python! Hari ini, kita akan memulakan perjalanan yang menarik ke atas dunia Penjana Python. Jangan khawatir jika anda belum pernah mendengar tentang mereka sebelum ini – kita akan bermula dari permulaan dan bekerja ke atas. Pada akhir tutorial ini, anda akan membuat penjana sepertimana professional!

Python - Generators

Apa itu Penjana Python?

Bayangkan anda sedang membaca buku yang sangat panjang. Daripada untuk fotokopi keseluruhan buku sekali (yang akan membazirkan banyak kertas!), anda boleh hanya membaca satu halaman pada satu masa. Itu adalah jenis yang sama seperti penjana bekerja di atas Python!

Penjana adalah jenis khusus fungsi yang membolehkan kita untuk menjana sekumpulan nilai berdasarkan masa, bukannya mengira mereka semua sekali dan menyimpan mereka di atas penyimpanan. Mereka seperti kilang penyihir yang menghasilkan nilai atas permintaan.

Mengapa Gunakan Penjana?

  1. Kecekapan Memori: Penjana adalah ramah kepada memori. Mereka tidak menyimpan semua nilai di atas penyimpanan sekali.
  2. Prestasi: Mereka boleh meningkatkan prestasi kod anda, khususnya apabila berurusan dengan dataset yang besar.
  3. Kepedahan: Penjana boleh menjadikan kod anda lebih bersih dan lebih mudah dibaca.

Mari kita melompat dan lihat bagaimana mereka bekerja!

Membuat Penjana

Ada dua cara utama untuk membuat penjana di atas Python:

  1. Menggunakan fungsi penjana
  2. Menggunakan ungkapan penjana

Fungsi Penjana

Fungsi penjana kelihatan seperti fungsi biasa, tetapi bukannya menggunakan kata kunci return, ia menggunakan yield. Di sini adalah contoh yang simple:

def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1

# Menggunakan penjana kami
for number in count_up_to(5):
print(number)

Output:

1
2
3
4
5

Dalam contoh ini, count_up_to adalah fungsi penjana. Setiap kali ia menghasilkan nilai, ia menangguhkan eksekusinya dan mengingati keadaannya. Pada masa berikutnya ia dipanggil, ia akan meneruskan dari tempat ia tinggalkan.

Ungkapan Penjana

Ungkapan penjana adalah seperti pemahaman rakisan, tetapi dengan kurungan bukannya rakisan. Mereka adalah cara ringkas untuk membuat penjana. Di sini adalah contoh:

# Ungkapan penjana
squares = (x**2 for x in range(5))

# Menggunakan penjana kami
for square in squares:
print(square)

Output:

0
1
4
9
16

Ungkapan penjana ini mencipta urutan angka kuasa dua atas permintaan, tanpa menyimpan mereka semua di atas penyimpanan sekali.

Pengurusanan Penyekat dalam Penjana

Penjana juga boleh mengurus penyekat, yang adalah sangat keren! Di sini adalah contoh:

def div_generator(a, b):
try:
result = a / b
yield result
except ZeroDivisionError:
yield "Tidak boleh bahagi dengan nol!"

# Menggunakan penjana kami
g = div_generator(10, 2)
print(next(g))  # Cetak: 5.0

g = div_generator(10, 0)
print(next(g))  # Cetak: Tidak boleh bahagi dengan nol!

Dalam contoh ini, penjana kita dengan lembut mengurus kasus di mana kita cuba untuk bahagi dengan nol.

Fungsi Biasa vs Fungsi Penjana

Mari kita bandingkan fungsi biasa dengan fungsi penjana untuk melihat perbezaannya:

# Fungsi biasa
def get_squares(n):
squares = []
for i in range(n):
squares.append(i**2)
return squares

# Fungsi penjana
def gen_squares(n):
for i in range(n):
yield i**2

# Menggunakan fungsi biasa
print(get_squares(5))  # Cetak: [0, 1, 4, 9, 16]

# Menggunakan fungsi penjana
for square in gen_squares(5):
print(square)  # Cetak setiap rakisan pada baris baru

Perbezaannya adalah:

  1. Penggunaan memori: Fungsi biasa mencipta dan menyimpan semua nilai sekali, sementara penjana menghasilkan mereka satu pada satu.
  2. Sintaks: Fungsi biasa menggunakan return, sementara penjana menggunakan yield.
  3. Iterasi: Penjana boleh diiterasi secara langsung, sementara hasil fungsi biasa perlu disimpan di atas pembolehubah dahulu.

Penjana Asinkron

Python 3.6 memperkenalkan penjana asinkron, yang adalah seperti penjana biasa tetapi untuk pengaturcaraan asinkron. Mereka menggunakan async def dan yield:

import asyncio

async def async_gen():
for i in range(3):
await asyncio.sleep(1)
yield i

async def main():
async for item in async_gen():
print(item)

asyncio.run(main())

Contoh ini mensimulasikan operasi asinkron yang menghasilkan nilai berdasarkan masa.

Method Penjana

Penjana ada beberapa method khas yang boleh menjadi sangat berguna. Di sini adalah jadual bagi yang paling umum:

Method Keterangan
next() Mengambil item berikutnya dari penjana
send() Menghantar nilai ke atas penjana
throw() Menghantar penyekat di atas penjana
close() Menutup penjana

Di sini adalah contoh cepat penggunaan send():

def echo_generator():
while True:
received = yield
print(f"Received: {received}")

g = echo_generator()
next(g)  # Prime the generator
g.send("Hello")  # Cetak: Received: Hello
g.send("World")  # Cetak: Received: World

Dan itu adalah semua! Anda baru saja mengambil langkah pertama anda ke atas dunia yang menarik Penjana Python. Ingat, praktek membuat perfect, jadi jangan takut untuk untuk bereksperimen dengan konsep ini. Sebelum anda tahu, anda akan menggunakan penjana untuk mengatasi semua jenis masalah yang menarik dalam program Python anda. Happy coding!

Credits: Image by storyset