Những chức năng nào functools.partial
cung cấp mà bạn không thể có được thông qua lambdas?
Không nhiều về chức năng bổ sung (nhưng, xem sau) - và, khả năng đọc là trong mắt của kẻ si tình.
Hầu hết những người quen thuộc với các ngôn ngữ lập trình chức năng (đặc biệt là những người trong gia đình Lisp / Scheme) dường như rất thích lambda
- tôi nói "nhất", chắc chắn không phải tất cả, bởi vì Guido và tôi chắc chắn nằm trong số những người "quen thuộc" (v.v. ) chưa nghĩ đến lambda
sự bất thường trong Python ...
Anh ta đã hối hận vì đã từng chấp nhận nó vào Python trong khi dự định xóa nó khỏi Python 3, như một trong những "trục trặc của Python".
Tôi hoàn toàn ủng hộ anh ấy trong đó. (Tôi thích lambda
Scheme ... trong khi những hạn chế của nó trong Python và cách kỳ lạ mà nó không làm được ' với phần còn lại của ngôn ngữ, làm cho da tôi bò lên).
Không phải như vậy, tuy nhiên, đối với đám lambda
người yêu - người dàn dựng một trong những điều gần gũi nhất với một cuộc nổi loạn từng thấy trong lịch sử của Python, cho đến khi Guido rút lui và quyết định rời khỏi lambda
. Trong
số bổ sung có thể functools
(để thực hiện chức năng trở về hằng số, nhận dạng, v.v.) đã không xảy ra (để tránh sao chép rõ ràng nhiều lambda
chức năng hơn), mặc dù partial
tất nhiên vẫn còn (nó không hoàn toàn trùng lặp, cũng không phải là chướng mắt).
Hãy nhớ rằng lambda
cơ thể của chúng bị giới hạn là một biểu thức , vì vậy nó có những hạn chế. Ví dụ...:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial
Hàm trả về được trang trí với các thuộc tính hữu ích cho việc xem xét nội bộ - chức năng mà nó bao bọc, và các đối số vị trí và được đặt tên mà nó sửa trong đó. Hơn nữa, các đối số được đặt tên có thể được ghi đè lại ngay ("sửa lỗi", theo một nghĩa nào đó, cài đặt mặc định):
>>> f('23', base=10)
23
Vì vậy, như bạn thấy, nó definely không phải là đơn giản như lambda s: int(s, base=2)
-!)
Có, bạn có thể buộc lambda của bạn cung cấp cho bạn một số điều này - ví dụ: đối với từ khóa ghi đè,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
nhưng tôi hy vọng rằng ngay cả những người hăng hái nhất lambda
cũng không coi điều kinh dị này dễ đọc hơn partial
cuộc gọi! -). Phần "cài đặt thuộc tính" thậm chí còn khó hơn, vì giới hạn "cơ thể là một biểu thức" của Python lambda
(cộng với thực tế là phép gán không bao giờ là một phần của biểu thức Python) ... bạn kết thúc "giả mạo bài tập trong một biểu thức" bằng cách kéo dài sự hiểu biết danh sách vượt quá giới hạn thiết kế của nó ...:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
Bây giờ, hãy kết hợp tính quá mức của các đối số được đặt tên, cộng với việc thiết lập ba thuộc tính, thành một biểu thức duy nhất và cho tôi biết mức độ dễ đọc của nó !
functools.partial
mà bạn đề cập làm cho nó vượt trội hơn lambda. Có lẽ đây là chủ đề của một bài viết khác, nhưng nó ở cấp độ thiết kế nào làm phiền bạn rất nhiềulambda
?