Trong hướng dẫn này, bạn sẽ tìm hiểu cách tạo các lần lặp dễ dàng bằng cách sử dụng trình tạo Python, nó khác với trình lặp và các hàm thông thường như thế nào và tại sao bạn nên sử dụng nó.
Trình tạo bằng Python
Có rất nhiều công việc trong việc xây dựng một trình lặp trong Python. Chúng ta phải triển khai một lớp với __iter__()
và __next__()
phương thức, theo dõi các trạng thái bên trong và nâng lên StopIteration
khi không có giá trị nào được trả về.
Điều này vừa dài dòng vừa phản trực giác. Máy phát điện đến để giải cứu trong những tình huống như vậy.
Trình tạo Python là một cách đơn giản để tạo trình vòng lặp. Tất cả công việc mà chúng tôi đã đề cập ở trên đều được xử lý tự động bởi các trình tạo bằng Python.
Nói một cách đơn giản, trình tạo là một hàm trả về một đối tượng (trình lặp) mà chúng ta có thể lặp lại (một giá trị tại một thời điểm).
Tạo trình tạo bằng Python
Nó khá đơn giản để tạo một trình tạo bằng Python. Nó dễ dàng như xác định một hàm bình thường, nhưng với một yield
câu lệnh thay vì một return
câu lệnh.
Nếu một hàm chứa ít nhất một yield
câu lệnh (nó có thể chứa các câu lệnh yield
hoặc return
câu lệnh khác), nó sẽ trở thành một hàm tạo. Cả hai yield
và return
sẽ trả về một số giá trị từ một hàm.
Sự khác biệt là trong khi một return
câu lệnh kết thúc hoàn toàn một hàm, yield
câu lệnh sẽ tạm dừng hàm lưu tất cả các trạng thái của nó và sau đó tiếp tục từ đó với các lệnh gọi kế tiếp.
Sự khác biệt giữa chức năng Máy phát điện và chức năng Bình thường
Đây là cách một hàm máy phát điện khác với một hàm bình thường .
- Hàm tạo chứa một hoặc nhiều
yield
câu lệnh. - Khi được gọi, nó trả về một đối tượng (trình lặp) nhưng không bắt đầu thực thi ngay lập tức.
- Các phương thức như
__iter__()
và__next__()
được thực hiện tự động. Vì vậy, chúng tôi có thể lặp qua các mục đang sử dụngnext()
. - Khi chức năng mang lại, chức năng sẽ bị tạm dừng và quyền điều khiển được chuyển cho người gọi.
- Các biến cục bộ và trạng thái của chúng được ghi nhớ giữa các lần gọi liên tiếp.
- Cuối cùng, khi chức năng kết thúc,
StopIteration
sẽ tự động được nâng lên trong các lần gọi tiếp theo.
Đây là một ví dụ để minh họa tất cả các điểm đã nêu ở trên. Chúng ta có một hàm tạo được đặt tên my_gen()
với một số yield
câu lệnh.
# A simple generator function
def my_gen():
n = 1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
Dưới đây là một cuộc chạy tương tác trong trình thông dịch. Chạy chúng trong trình bao Python để xem kết quả.
>>> # It returns an object but does not start execution immediately.
>>> a = my_gen()
>>> # We can iterate through the items using next().
>>> next(a)
This is printed first
1
>>> # Once the function yields, the function is paused and the control is transferred to the caller.
>>> # Local variables and theirs states are remembered between successive calls.
>>> next(a)
This is printed second
2
>>> next(a)
This is printed at last
3
>>> # Finally, when the function terminates, StopIteration is raised automatically on further calls.
>>> next(a)
Traceback (most recent call last):
...
StopIteration
>>> next(a)
Traceback (most recent call last):
...
StopIteration
Một điều thú vị cần lưu ý trong ví dụ trên là giá trị của biến n được ghi nhớ giữa mỗi cuộc gọi.
Không giống như các hàm thông thường, các biến cục bộ không bị hủy khi hàm cho kết quả. Hơn nữa, đối tượng trình tạo chỉ có thể được lặp lại một lần.
Để khởi động lại quá trình, chúng ta cần tạo một đối tượng trình tạo khác bằng cách sử dụng một cái gì đó như a = my_gen()
.
Một điều cuối cùng cần lưu ý là chúng ta có thể sử dụng máy phát điện với vòng lặp for một cách trực tiếp.
Điều này là do một for
vòng lặp sử dụng một trình lặp và lặp lại nó bằng cách sử dụng next()
hàm. Nó tự động kết thúc khi StopIteration
được nâng lên. Kiểm tra ở đây để biết vòng lặp for thực sự được triển khai như thế nào trong Python .
# A simple generator function
def my_gen():
n = 1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
# Using for loop
for item in my_gen():
print(item)
Khi bạn chạy chương trình, kết quả đầu ra sẽ là:
Cái này được in đầu tiên
1
Đây được in lần thứ hai
2
Điều này được in cuối cùng
3