Khóa học Phát triển Python Nâng cao
Chương
>
Cấp độ
Máy Sinh Máy sinh (Generators) là một tính năng mạnh mẽ trong Python cho phép tạo ra một chuỗi các giá trị theo cách hiệu quả. Không giống như việc xây dựng toàn bộ danh sách trong bộ nhớ, máy sinh tạo ra giá trị theo yêu cầu và chỉ lưu trữ giá trị tạm thời, điều này làm giảm việc sử dụng bộ nhớ. ### Cách Tạo Máy Sinh Bạn có thể tạo một máy sinh bằng cách sử dụng hàm với từ khóa `yield`. Khác với `return`, `yield` cho phép một hàm tạm ngưng và tiếp tục từ nơi nó đã dừng lại. Điều này hữu ích khi làm việc với các tập dữ liệu lớn hoặc luồng dữ liệu vô hạn. ```python # Một ví dụ máy sinh đếm từ 0 đến `n` def count_up_to(n): count = 0 while count <= n: yield count count += 1 ``` Trong ví dụ trên, hàm `count_up_to` là một máy sinh. Mỗi lần `yield` được gọi, hàm tạm dừng, và điều khiển được trả lại cho người gọi. Khi `next()` được gọi trên máy sinh, hàm sẽ tiếp tục từ nơi nó đã dừng lại. ### Sử Dụng Máy Sinh Để sử dụng máy sinh, chúng ta có thể sử dụng vòng lặp `for` hoặc gọi `next()`: ```python counter = count_up_to(5) # Sử dụng vòng lặp foror number in counter: print(number) # Hoặc sử dụng next() # counter = count_up_to(3) #print(next(counter)) # 0 #print(next(counter)) # 1 #print(next(counter)) # 2 ``` Khi sử dụng máy sinh, không cần phải lo lắng về việc đạt đến giới hạn bộ nhớ, vì giá trị chỉ được tạo ra khi cần.
Tạo Generator
Đôi khi bạn có thể muốn tạo ra giá trị một cách nhất quán thay vì chỉ một lần duy nhất. Tương tự như cách hoạt động của các hàm, các generator được viết và thực thi theo cùng một cách, ngoại trừ việc chúng sử dụng yield() thay vì return() khi tạo ra một đầu ra.
Trong bài tập này, bạn phải đổ sữa vào chai từ bể chứa tại trang trại. Sử dụng một generator để lặp lại việc đổ đầy các chai và đảm bảo rằng bất kỳ lượng sữa dư thừa nào cũng được thu thập từ bể chứa.

Mục Tiêu
Đổ sữa vào chai bằng cách bơm các bồn sữa sử dụng máy phát điện.
Các máy lưu trữ sữa bò gần như đã đầy, bạn cần đổ sữa vào chai và lưu trữ nó trước khi nó hỏng. Đây có thể là một nhiệm vụ hơi khó khăn nếu sử dụng các phương pháp thông thường, và lượng sữa bạn có thể chiết ra có thể dao động chút ít. May mắn thay, bạn có thể sử dụng máy phát điện để làm cho quá trình này dễ dàng và đơn giản.
Có hai (2) bồn chứa sữa cần được bơm và đóng chai. Mỗi máy có các ngăn lưu trữ sữa, những ngăn này được biểu diễn bằng các hằng danh sách được đặt tên: tank_a và tank_b. Ngoài ra, mỗi bồn có xu hướng có dư thừa mà bạn có thể thu thập.
Máy phát điện sử dụng cùng cú pháp như hàm nhưng sẽ sử dụng yield thay vì return cho đầu ra của chúng. Thiết lập một máy phát điện tên là fill() và cài đặt nó với tham số list, đây sẽ là nơi bạn nhập các hằng được nhắc trong đoạn văn trên.
def fill(list):
for x in range(3):
yield list[x]
yield 5
Máy phát điện đọc dữ liệu từ ba (3) trường trong các hằng danh sách, đại diện cho các ngăn trong máy, và thêm một phần dư thừa vào cuối đó là năm (5).
Thu thập đối tượng giỏ trong trường để có quyền truy cập vào các chai cần thiết để đổ và đi đến hai (2) vị trí X để thu thập sữa bằng cách sử dụng vòng lặp for.
Nhờ vào câu lệnh yield, các giá trị được sản sinh từ máy phát điện có thể được đọc trực tiếp từ vòng lặp for. Thiết lập một cái và sử dụng hàm collect() để thu được "sữa" từ máy. Tiếp theo, sử dụng speak() để kiểm tra xem mỗi chai đã lưu trữ bao nhiêu sữa. Ví dụ:
for bottles in fill(tank_a): player.collect("milk") player.speak("%d pints of milk collected" % (bottles))
Viết và sử dụng vòng lặp for này trên cả hai dấu X, trên dấu X sáng sử dụng tham số tank_a và trên dấu X tối sử dụng tham số tank_b để hoàn thành cấp độ.