Bạn có thể sử dụng return
một lần trong máy phát điện; nó ngừng lặp lại mà không mang lại bất cứ điều gì và do đó cung cấp một giải pháp thay thế rõ ràng để cho phép hàm chạy ra khỏi phạm vi. Vì vậy, hãy sử dụng yield
để biến hàm thành một trình tạo, nhưng đặt trước nó return
để kết thúc trình tạo trước khi mang lại bất kỳ thứ gì.
>>> def f():
... return
... yield
...
>>> list(f())
[]
Tôi không chắc nó tốt hơn nhiều so với những gì bạn có - nó chỉ thay thế một if
câu lệnh no-op bằng một câu no-op yield
. Nhưng nó mang tính thành ngữ hơn. Lưu ý rằng chỉ sử dụng yield
không hoạt động.
>>> def f():
... yield
...
>>> list(f())
[None]
Tại sao không chỉ sử dụng iter(())
?
Câu hỏi này hỏi cụ thể về một chức năng tạo trống . Vì lý do đó, tôi coi đây là câu hỏi về tính nhất quán bên trong của cú pháp Python, chứ không phải là câu hỏi về cách tốt nhất để tạo một trình lặp trống nói chung.
Nếu câu hỏi thực sự là về cách tốt nhất để tạo một trình lặp trống, thì bạn có thể đồng ý với Zectbumo về việc sử dụng iter(())
thay thế. Tuy nhiên, điều quan trọng là phải quan sát rằng iter(())
nó không trả về một hàm! Nó trực tiếp trả về một giá trị có thể lặp lại trống. Giả sử bạn đang làm việc với một API mong đợi một hàm có thể gọi trả về một giá trị có thể lặp lại. Bạn sẽ phải làm điều gì đó như sau:
def empty():
return iter(())
(Tín dụng sẽ thuộc về Unutbu vì đã đưa ra phiên bản chính xác đầu tiên của câu trả lời này.)
Bây giờ, bạn có thể thấy điều trên rõ ràng hơn, nhưng tôi có thể tưởng tượng những tình huống mà nó sẽ kém rõ ràng hơn. Hãy xem xét ví dụ này về một danh sách dài các định nghĩa hàm của trình tạo (tiếp theo):
def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
Ở cuối danh sách dài đó, tôi muốn xem một cái gì đó có một yield
trong đó, như thế này:
def empty():
return
yield
hoặc, trong Python 3.3 trở lên (theo đề xuất của DSM ), điều này:
def empty():
yield from ()
Sự hiện diện của yield
từ khóa làm rõ ràng rằng đây chỉ là một hàm trình tạo khác, giống hệt như tất cả các hàm khác. Cần thêm một chút thời gian để thấy rằng iter(())
phiên bản đang làm điều tương tự.
Đó là một sự khác biệt nhỏ, nhưng tôi thành thật nghĩ rằng các yield
hàm dựa trên cơ sở này dễ đọc và dễ bảo trì hơn.
if False: yield
nhưng vẫn kinda khó hiểu đối với những người không biết mô hình này