INTRODUCTION
FLOW CONTROL
FUNCTIONS
DATATYPES
OBJECT & CLASS
Bài tập Python: Lập trình hướng đối tượng (OOP) trong Python Lập trình hướng đối tượng trong Python Class Variables trong Python Tìm hiểu về Methods trong Python Cách sử dụng phương thức __init__() trong Python Các biến Instance trong Python Tìm hiểu về Class Attributes trong Python Hàm Static Methods trong Python Phương thức __str__ trong Python Phương thức __repr__ trong Python Phương thức eq trong Python Tìm hiểu phương thức __hash__ trong Python Phương thức __bool__ trong Python Phương thức del trong Python Tìm hiểu về lớp Property trong Python Tìm hiểu về nạp chồng toán tử trong Python Trình Decorator Property trong Python Thuộc tính chỉ đọc trong Python Thuộc tính Delete trong Python Sử dụng super() trong Python Sử dụng __slots__ trong Python Cách sử dụng Protocol trong Python Sử dụng Enum aliases và @enum.unique trong Python Tùy chỉnh và mở rộng lớp Enum trong Python Cách sử dụng hàm Auto() của Python Single Responsibility Principle trong Python Nguyên tắc Đóng-Mở trong Python Nguyên tắc thay thế Liskov - LSP trong Python Interface Segregation Principle - ISP trong Python. Nguyên tắc đảo ngược sự phụ thuộc trong Python Đa kế thừa trong Python Tìm hiểu về các lớp mixin trong Python Mô tả Descriptors trong Python Phân biệt Data Descriptor và Non-data Descriptor trong Python Phương thức __new__ trong Python Tìm hiểu về Class Type trong Python Lớp Metaclass trong Python Ví dụ sử dụng metaclass trong Python Tìm hiểu về decorator dataclass trong Python Tìm hiểu về các ngoại lệ trong Python Ngoại lệ Raise trong Python Sử dụng câu lệnh raise from trong Python Ngoại lệ tùy chỉnh trong Python Module trong Python Package trong Python Class trong Python Hàm khởi tạo trong Python Kế thừa trong Python Đa kế thừa trong Python Setter và Getter trong Python Override trong Python Interface trong Python Bài tập Python: Module và Class
ADVANCED TOPICS
BỔ SUNG
PYTHON CĂN BẢN
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Generator trong Python

Trong bài này chúng ta sẽ tìm hiểu về Generator trong Python, đây là cách giúp bạn tạo ra một đối tượng iterator cực kì dễ dàng. Bên cạn đó mình cũng phân tích giúp bạn hiểu được sự khác nhau giữa một hàm bình thường và một hàm generator.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Generators trong Python là gì?

Generator là cách tạo ra một mô hình lặp iterator trong Python, bằng cách sử dụng từ khóa yield để tạo ra những trình lặp một cách đơn giản và hiệu quả nhất.

Một hàm khi sử dụng yield thì bản thân nó đã tự kế thừa hai phương thức __iter__()__next__() nên ta có thể sử dụng hàm next() mà không cần phải sử dụng hàm iter() để khởi tạo iterator.

2. Cách tạo Generators trong Python

Việc tạo một generator trong Python khá là đơn giản, nó giống như một hàm bình thường, nhưng thay vì sử dụng lệnh return để trả về thì ta sử dụng lệnh yield.

Bài viết này được đăng tại [free tuts .net]

Nếu một function (hàm) có chứa một hoặc nhiều lệnh yield thì nó là một generator. Một hàm có thể có một hoặc nhiều lệnh yield đặt tại nhiều vị trí khác nhau trong hàm.

Sự khác nhau giữa lệnh return và yield là trong khi return sẽ trả về một giá trị và kết thúc hàm, nhưng yield thì sẽ trả về nhưng vẫn giữ lại trạng thái của các biến, sau đó nếu được gọi tiếp thì nó sẽ tiếp tục xử lý ngay tại vị trí tạm dừng đó.

3. Sự khác nhau giữa hàm generator và hàm bình thường

Dưới đây là một vài điểm khác nhau giữa hàm generator và hàm bình thường.

  • Generator chứa một hoặc nhiều lệnh yield.
  • Khi được gọi, hàm generator sẽ trả về một đối tượng iterator nhưng nó không thực thi liền.
  • Hai phương thức __iter__()__next__() được kế thừa tự động, vì vậy bạn có thể sử dụng hàm next() mà không cần dùng hàm iter() để tạo iterator .
  • Trạng thái của các biến được lưu trữ lại giữa những lần gọi.
  • Cuối cùng khi hàm kết thúc thì StopIteration sẽ bung ra cho lần gọi hàm tiếp theo, đây là lỗi cho thấy iterator đã duyệt đến phần tử cuối cùng.

Hãy xem ví dụ dưới đây để hiểu rõ hơn.

# HỌC PYTHON TAI FREETUTS.NET
# AUTHOR: CƯỜNG NGUYỄN
def generateNumber():
    n = 1
    print("Lần gọi thứ nhất trả về n = ", n)
    yield n

    n += 1
    print("Lần gọi thứ hai trả về n = ", n)
    yield n

    n += 1
    print("Lần gọi thứ ba trả về n = ", n)
    yield n

# Chương trình chính
num = generateNumber()

# Kiểm tra xe num là gì?
# => Nó là một generate object
# <generator object generateNumber at 0x000001CD0A939510>
print(num)

# Gọi đến generate => trả về yield đầu tiên
# Kết quả: 1
print(next(num))

# Gọi đến generate => trả về yield thứ hai
# Kết quả: 2
print(next(num))

# Gọi đến generate => trả về yield thứ ba
# Kết quả: 3
print(next(num))

Như bạn thấy, biến n bên trong hàm đã được nhớ sau mỗi lần gọi.

4. Sử dụng vòng lặp trong Generator Python

Ở ví dụ trên mình chỉ giải thích cách hoạt động của generator chứ thực tế không ai làm như vậy.

Chúng ta thường sử dụng vòng lặp để tạo ra những generator.

Hãy xem ví dụ dưới đây, mình sẽ tạo ra một generator các số từ 1 đến 10.

# Tạo generator
def generateNumber():
    for i in range(1, 11):
        yield i

# Lặp qua generator
num = generateNumber()
for n in num:
    print(n)

Kết quả như sau:

ket qua generator JPG

5. Sử dụng generator expression trong Python

Ngoài những cách trên thì bạn có thể tạo ra generator bằng biểu thức expression.

Cách hoạt động của nó giống như list comprehension, chỉ có điều một bên sử dụng dấu ngoặc vuông, một bên sử dụng dấu ngoặc nhọn.

Cách này chỉ phù hợp với những trường hợp có list data sẵn, và bạn muốn tạo ra một generator dựa trên list đó.

# Tạo list
my_list = [1, 3, 6, 10]

# Sử dụng expression để tạo generator
generator = (x**2 for x in my_list)

for item in generator:
    print(item)

Kết quả:

generator python JPG

Ta có thể viết lại ví dụ trên bằng cách sử dụng vòng lặp như sau:

# Tạo list
my_list = [1, 3, 6, 10]

# Sử dụng vòng lặp
def newList(my_list):
    for item in my_list:
        yield item

generator = newList(my_list)

for item in generator:
    print(item)

6. Tại sao nên dùng generator trong Python?

Lý do đơn giản và thuyết phục nhất là generator rất đơn giản và dễ thực hiện.

Generator triển khai dễ dàng và ngắn gọn hơn nhiều so với việc sử dụng trình lặp của iterator.

Ví dụ: Xây dựng một iterator tính lũy thừa của 2.

class LuyThua2():
    def __init__(self, max = 0):
        # Thuộc tính lưu số lũy thừa hiện tại
        self.n = 0
        # Thuộc tính lưu số lũy thừa tối đa
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        if self.n > self.max:
            raise StopIteration
        else:
            result = 2 ** self.n
            self.n += 1
            return result


l = LuyThua2(5)

print(next(l)) # n = 0
print(next(l)) # n = 1
print(next(l)) # n = 2
print(next(l)) # n = 3
print(next(l)) # n = 4
print(next(l)) # n = 5

print(next(l)) # Trả về lỗi StopIteration

Nhưng nếu viết bằng Generator thì chương trình rất ngắn gọn như sau:

def LuyThua2(max = 0):
    n = 0
    while n <= max:
        yield 2 ** n
        n += 1

l = LuyThua2(5)
print(next(l)) # n = 1
print(next(l)) # n = 2
print(next(l)) # n = 3
print(next(l)) # n = 4
print(next(l)) # n = 5
print(next(l)) # n = 6
print(next(l)) # Lỗi StopIteration

Ngoài ra, generator thân thiện hơn bởi nó chỉ tạo ra một mục tại một thời điểm gọi.

Trên là những chia sẻ cơ bản về cách sử dụng generator trong Python.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top