Tại sao các trình tạo và chức năng python chia sẻ từ khóa của def def?


10

Hãy xem xét những điều sau đây:

def some_function():
    return 1

def some_generator():
    yield 1

Trong đoạn mã trên, some_functionlà một hàm, trong khi some_generatorlà một trình tạo. Chúng trông khá giống nhau.

Vấn đề mà tôi gặp phải khi đọc mã là tôi cần quét qua từng dòng trong một "hàm" tìm kiếm yieldtừ khóa trước khi tôi có thể xác định xem đó thực sự là một hàm hay một trình tạo!

Dường như với tôi rằng việc sử dụng một từ khóa khác cho các trình tạo sẽ có ý nghĩa hơn, ví dụ:

gen some_generator():
    yield 1

Ưu điểm của việc sử dụng deftừ khóa cho cả trình tạo và hàm là gì? Tại sao một từ khóa mới không được giới thiệu cho các chức năng và trình tạo riêng biệt?


Tôi không biết câu trả lời thực sự, nhưng tôi thường bắt đầu viết các hàm trả về danh sách, sau đó chuyển đổi sang các trình tạo khi nó có vẻ đúng. Có cú pháp phù hợp làm cho điều này tự nhiên hơn.
Gort Robot

2
@StevenBurnap Đề xuất của Derek về việc sử dụng một cái gì đó như genthay vì defsẽ không làm cho sự biến đổi đó trở nên tồi tệ hơn đáng kể.
jamesdlin

1
Nói chung, các nhà thiết kế ngôn ngữ thường cố gắng tránh thêm các từ khóa không cần thiết. Mỗi từ khóa họ thêm là một định danh mà các chương trình không được phép sử dụng cho các mục đích khác.
jamesdlin

@jamesdlin: Nhưng câu hỏi đang tranh luận rằng một từ khóa mới sẽ là cần thiết .
Giorgio

1
@jamesdlin: Tất nhiên bạn có thể phân biệt các hàm và trình tạo bằng cách nhìn vào cơ thể của chúng, nhưng câu hỏi lập luận rằng sử dụng các từ khóa khác nhau sẽ làm cho mã dễ đọc hơn.
Giorgio

Câu trả lời:


14

"Những lợi ích của việc sử dụng từ khóa def cho cả trình tạo và hàm là gì?"

Mặc dù chúng khác nhau về mặt cơ học, nhưng trong thực tế khi tôi sử dụng chúng, chúng thường giống nhau về mặt khái niệm (tôi không nghĩ nhiều về việc gọi range()vs xrange()).

Về mặt hiểu biết chức năng là gì một cách nhanh chóng, tôi đồng ý rằng một cái gì đó bị mất khi sử dụng def, nhưng mọi thứ không nên quá khó hiểu trong chức năng để bắt đầu.

Ngay cả một ẩn return Nonecó thể nhầm lẫn hành vi dự định của một chức năng sau một chút dài các điều kiện (như trong, là một return Nonedự định như một hành vi cuối cùng hoặc một sự giám sát trong logic). Nhưng đó chỉ là những niềm tin của tôi về nó.

Mặc dù vậy, tôi không cảm thấy lập luận của mình đặc biệt thuyết phục vì vậy tôi sẽ chỉ trì hoãn PEP 255 :

Vấn đề: Giới thiệu một từ khóa mới khác (giả sử là "gen" hoặc "trình tạo") thay cho "def" hoặc thay đổi cú pháp để phân biệt các hàm của trình tạo với các hàm không tạo.

Con: Trong thực tế (cách bạn nghĩ về chúng), máy phát điện là các chức năng, nhưng với sự thay đổi mà chúng có thể phục hồi được. Các cơ chế về cách chúng được thiết lập là một vấn đề kỹ thuật tương đối nhỏ và việc giới thiệu một từ khóa mới sẽ vô tình nhấn mạnh đến các cơ chế về cách các máy phát điện bắt đầu (một phần quan trọng nhưng rất nhỏ trong cuộc sống của máy phát điện).

Pro: Trong thực tế (cách bạn nghĩ về chúng), các chức năng của máy phát thực sự là các chức năng của nhà máy tạo ra các trình tạo vòng lặp như thể bằng phép thuật. Về mặt này, chúng hoàn toàn khác với các hàm không tạo, hoạt động giống như một hàm tạo hơn là một hàm, vì vậy việc sử dụng lại "def" là khó hiểu nhất. Một tuyên bố "năng suất" chôn trong cơ thể là không đủ cảnh báo rằng ngữ nghĩa là rất khác nhau.

BDFL: "def" nó vẫn còn. Không có tranh luận ở hai bên là hoàn toàn thuyết phục, vì vậy tôi đã tham khảo trực giác của nhà thiết kế ngôn ngữ của tôi. Nó cho tôi biết rằng cú pháp được đề xuất trong PEP là hoàn toàn chính xác - không quá nóng, không quá lạnh. Nhưng, giống như Oracle tại Delphi trong thần thoại Hy Lạp, nó không cho tôi biết lý do tại sao, vì vậy tôi không phản bác lại các lập luận chống lại cú pháp PEP. Điều tốt nhất tôi có thể đưa ra (ngoài việc đồng ý với các phản bác ... đã được thực hiện) là "FUD". Nếu đây là một phần của ngôn ngữ từ ngày đầu tiên, tôi rất nghi ngờ nó sẽ tạo ra trang "Python Warts" của Andrew Kuchling.


1
Điều đáng chú ý là mới await(và async withasync for) các cấu trúc cú pháp bổ sung trong PEP 492 , mà làm việc rất giống với yield from, yêu cầu các chức năng mà họ đang sử dụng trong được khai báo sử dụng async defthay vì một chỉ def.
Feuermurmel

2
  1. Thêm từ khóa mới có nguy cơ phá vỡ các chương trình hiện có. Các nhà thiết kế ngôn ngữ thường cố gắng tránh thêm các từ khóa mới, đặc biệt là các tính năng ngôn ngữ được thêm sau khi ngôn ngữ đã trở nên phổ biến. Mỗi từ khóa họ thêm là một định danh mà các chương trình không được phép sử dụng cho các mục đích khác, vì vậy việc thêm một từ khóa có khả năng phá vỡ các chương trình hiện có. Các nhà thiết kế ngôn ngữ phải cân nhắc lợi ích của một từ khóa mới so với chi phí.

  2. Tôi nghi ngờ rằng việc xác định các từ khóa riêng biệt sẽ có nhiều lợi ích. Để hiểu liệu một biểu tượng tương ứng với tên của hàm hay tên của trình tạo là điều quan trọng đối với người gọi và người gọi không nên (và đôi khi không thể) nhìn vào từ khóa nào được sử dụng để thực hiện nó. Đó là trách nhiệm của các quy ước và tài liệu đặt tên tốt hơn.


1

Máy phát điện là các chức năng đánh giá một cách lười biếng. Cho rằng chúng là cùng một thứ ở cơ sở, có nghĩa là chúng sẽ sử dụng cùng một từ khóa. Một tùy chọn có thể là sử dụng một nhận xét để xác định đó là ví dụ cụ thể:

def some_function(): #This is a function.
    return 1

def some_generator(): #This is a generator.
    yield 1

0

Tôi đoán nó là bởi vì nó là Pythonic hơn nhưng tôi biết gì? ;)

Tôi thực sự không nghĩ rằng nó quan trọng đến thế. Nó dễ nhớ hơn đối với tôi vì không cần phải ghi nhớ cả hai.

EDIT: PEP có thể nói, bạn có thể điều tra ở đó.


Cảm ơn! Trong thực tế, PEP không nói! Xem PEP-255 để biết những ưu / nhược điểm và quyết định cuối cùng liên quan đến từ khóa mới cho máy phát điện.
Derek Kwok

Với ý nghĩa Pythonic: "Cách nó được thực hiện trong Python"?
Giorgio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.