Ml giải pháp bài tập Coursera-python

Python có hàm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
3 để đặt thuộc tính của đối tượng đã cho. Bạn có thể sử dụng nó trong biểu thức lambda của mình

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
3 rất hữu ích khi bạn muốn lập trình chính xác [xin lỗi] đặt một số lớp hoặc thể hiện của lớp. Nó không được sử dụng thường xuyên vì việc gán biến trực tiếp với biểu thức
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
5 sẽ dễ dàng hơn. Nhưng đối với lambda. Đó là một sự cứu rỗi

Ngoài ra, các iterables hỗ trợ mục cài đặt [chẳng hạn như danh sách], bạn có thể sử dụng ________ 06

lựa chọn 1. Nếu bạn biết tên của biến bạn đang chỉ định

x = lambda nameofvar, value: setattr[__builtins__, nameofvar, value]

# abc does not exist right now. Assigning and setting it to 10
x['abc', 10]
print[abc] # output: 10

alt, nếu bạn muốn đặt thuộc tính của đối tượng

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500

Lựa chọn 2. Tạo một lớp tùy chỉnh và biến biến thành thể hiện của nó

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25

Tùy chọn 3. Để đặt mục của đối tượng

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]

Lợi thế duy nhất mà một biểu thức

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7 có trên một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
8 là
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7 có thể được nhúng ẩn danh trong một biểu thức lớn hơn. Nếu bạn định gán tên cho một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7, tốt hơn hết bạn chỉ nên xác định nó là một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
8

Từ Hướng dẫn Phong cách PEP 8

Đúng

Không

The first form means that the name of the resulting function object is specifically ‘f’ instead of the generic ‘’. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement [i.e. that it can be embedded inside a larger expression]

Chống mẫu¶

Đoạn mã sau gán một hàm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7 trả về gấp đôi giá trị đầu vào của nó cho một biến. Chức năng này giống hệt với việc tạo một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
8

Thực hành tốt nhất¶

Sử dụng một def cho các biểu thức được đặt tên¶

Cấu trúc lại biểu thức

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7 thành biểu thức
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
8 có tên

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Cách sử dụng các hàm Lambda của Python

Python và các ngôn ngữ khác như Java, C# và thậm chí C++ đã có các hàm lambda được thêm vào cú pháp của chúng, trong khi các ngôn ngữ như LISP hoặc họ ngôn ngữ ML, Haskell, OCaml và F#, sử dụng lambdas làm khái niệm cốt lõi

Lambda Python là các hàm nhỏ, ẩn danh, có cú pháp hạn chế hơn nhưng ngắn gọn hơn các hàm Python thông thường

Đến cuối bài viết này, bạn sẽ biết

  • Python lambdas ra đời như thế nào
  • Làm thế nào lambdas so sánh với các đối tượng chức năng thông thường
  • Cách viết hàm lambda
  • Hàm nào trong thư viện chuẩn Python tận dụng lambdas
  • Khi nào nên sử dụng hoặc tránh các hàm lambda Python

Hướng dẫn này chủ yếu dành cho các lập trình viên Python có trình độ từ trung cấp đến có kinh nghiệm, nhưng bất kỳ ai có đầu óc tò mò quan tâm đến lập trình và phép tính lambda đều có thể truy cập được.

Tất cả các ví dụ trong hướng dẫn này đã được thử nghiệm với Python 3. 7

Phép tính Lambda

Các biểu thức lambda trong Python và các ngôn ngữ lập trình khác có nguồn gốc từ phép tính lambda, một mô hình tính toán được phát minh bởi Alonzo Church. Bạn sẽ khám phá ra khi phép tính lambda được giới thiệu và tại sao nó là một khái niệm cơ bản lại xuất hiện trong hệ sinh thái Python

Lịch sử

Nhà thờ Alonzo đã chính thức hóa phép tính lambda, một ngôn ngữ dựa trên sự trừu tượng thuần túy, vào những năm 1930. Các hàm lambda còn được gọi là trừu tượng lambda, một tham chiếu trực tiếp đến mô hình trừu tượng trong sáng tạo ban đầu của Alonzo Church

Phép tính Lambda có thể mã hóa bất kỳ phép tính nào. Nó là Turing hoàn chỉnh, nhưng trái ngược với khái niệm về máy Turing, nó thuần túy và không giữ bất kỳ trạng thái nào

Các ngôn ngữ hàm có nguồn gốc từ logic toán học và phép tính lambda, trong khi các ngôn ngữ lập trình mệnh lệnh sử dụng mô hình tính toán dựa trên trạng thái được phát minh bởi Alan Turing. Hai mô hình tính toán, phép tính lambda và máy Turing, có thể dịch sang nhau. Sự tương đương này được gọi là giả thuyết Church-Turing

Các ngôn ngữ hàm kế thừa trực tiếp triết lý tính toán lambda, áp dụng cách tiếp cận lập trình khai báo nhấn mạnh tính trừu tượng, chuyển đổi dữ liệu, thành phần và độ tinh khiết [không có trạng thái và không có tác dụng phụ]. Ví dụ về các ngôn ngữ chức năng bao gồm Haskell, Lisp hoặc Erlang

Ngược lại, Máy Turing dẫn đến lập trình mệnh lệnh được tìm thấy trong các ngôn ngữ như Fortran, C hoặc Python

Phong cách mệnh lệnh bao gồm lập trình với các câu lệnh, điều khiển dòng chảy của chương trình từng bước với các hướng dẫn chi tiết. Cách tiếp cận này thúc đẩy đột biến và yêu cầu quản lý trạng thái

Sự tách biệt trong cả hai họ thể hiện một số sắc thái, vì một số ngôn ngữ chức năng kết hợp các tính năng bắt buộc, như OCaml, trong khi các tính năng chức năng đã thấm vào họ ngôn ngữ bắt buộc, đặc biệt là với việc giới thiệu các hàm lambda trong Java hoặc Python

Python vốn dĩ không phải là một ngôn ngữ chức năng, nhưng nó đã sớm áp dụng một số khái niệm chức năng. Vào tháng 1 năm 1994,

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
78 và toán tử
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 đã được thêm vào ngôn ngữ

Ví dụ đầu tiên

Dưới đây là một vài ví dụ để giúp bạn cảm thấy ngon miệng với một số mã Python, kiểu chức năng

Hàm nhận dạng, một hàm trả về đối số của nó, được thể hiện bằng định nghĩa hàm Python tiêu chuẩn bằng cách sử dụng từ khóa

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
10 như sau

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
2

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
11 lấy một đối số
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 và trả về nó khi gọi

Ngược lại, nếu bạn sử dụng cấu trúc lambda Python, bạn sẽ nhận được thông tin sau

Trong ví dụ trên, biểu thức bao gồm

  • từ khóa.
    [lambda x: x + 1][2] = lambda 2: 2 + 1
                         = 2 + 1
                         = 3
    
    79
  • Một biến ràng buộc.
    [lambda x: x + 1][2] = lambda 2: 2 + 1
                         = 2 + 1
                         = 3
    
    12
  • Một cơ thể.
    [lambda x: x + 1][2] = lambda 2: 2 + 1
                         = 2 + 1
                         = 3
    
    12

Bạn có thể viết một ví dụ phức tạp hơn một chút, một hàm thêm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
16 vào một đối số, như sau

Bạn có thể áp dụng hàm ở trên cho một đối số bằng cách bao quanh hàm và đối số của nó bằng dấu ngoặc đơn

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
9

Giảm là một chiến lược tính toán lambda để tính giá trị của biểu thức. Trong ví dụ hiện tại, nó bao gồm việc thay thế biến ràng buộc

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 bằng đối số
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
18

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3

Vì hàm lambda là một biểu thức nên nó có thể được đặt tên. Do đó, bạn có thể viết mã trước đó như sau

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
7

Hàm lambda ở trên tương đương với việc viết cái này

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
1

Tất cả các chức năng này có một đối số duy nhất. Bạn có thể nhận thấy rằng, trong định nghĩa của lambdas, các đối số không có dấu ngoặc đơn xung quanh chúng. Các hàm nhiều đối số [các hàm nhận nhiều hơn một đối số] được thể hiện bằng lambdas Python bằng cách liệt kê các đối số và phân tách chúng bằng dấu phẩy [

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
19] nhưng không bao quanh chúng bằng dấu ngoặc đơn

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
6

Hàm lambda được gán cho

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
60 nhận hai đối số và trả về một chuỗi nội suy hai tham số
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
61 và
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
62. Như mong đợi, định nghĩa của lambda liệt kê các đối số không có dấu ngoặc đơn, trong khi việc gọi hàm được thực hiện chính xác như một hàm Python bình thường, với các dấu ngoặc đơn bao quanh các đối số

Hàm ẩn danh

Các thuật ngữ sau đây có thể được sử dụng thay thế cho nhau tùy thuộc vào loại ngôn ngữ lập trình và văn hóa

  • chức năng ẩn danh
  • hàm lambda
  • biểu thức lambda
  • trừu tượng lambda
  • biểu mẫu lambda
  • Hàm chữ

Đối với phần còn lại của bài viết này sau phần này, hầu như bạn sẽ thấy thuật ngữ hàm lambda

Theo nghĩa đen, một chức năng ẩn danh là một chức năng không có tên. Trong Python, một hàm ẩn danh được tạo bằng từ khóa

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79. Nói một cách lỏng lẻo hơn, nó có thể được đặt tên hoặc không. Xem xét hàm ẩn danh hai đối số được xác định bằng
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 nhưng không bị ràng buộc với một biến. Lambda không được đặt tên

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
0

Hàm trên định nghĩa một biểu thức lambda nhận hai đối số và trả về tổng của chúng

Ngoài việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với biểu mẫu này, nó không dẫn đến bất kỳ ứng dụng thực tế nào. Bạn có thể gọi hàm trong trình thông dịch Python

Ví dụ trên đang tận dụng tính năng chỉ dành cho trình thông dịch tương tác được cung cấp qua dấu gạch dưới [

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
65]. Xem ghi chú bên dưới để biết thêm chi tiết

Bạn không thể viết mã tương tự trong mô-đun Python. Hãy coi

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
65 trong trình thông dịch là một tác dụng phụ mà bạn đã lợi dụng. Trong một mô-đun Python, bạn sẽ gán tên cho lambda hoặc bạn sẽ chuyển lambda cho một hàm. Bạn sẽ sử dụng hai cách tiếp cận đó sau trong bài viết này

Một mẫu khác được sử dụng trong các ngôn ngữ khác như JavaScript là thực thi ngay hàm lambda Python. Đây được gọi là Biểu thức hàm được gọi ngay lập tức [IIFE, phát âm là “iffy”]. Đây là một ví dụ

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
1

Hàm lambda ở trên được xác định và sau đó được gọi ngay với hai đối số [

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
18 và
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
68]. Nó trả về giá trị
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
69, là tổng của các đối số

Một số ví dụ trong hướng dẫn này sử dụng định dạng này để làm nổi bật khía cạnh ẩn danh của hàm lambda và tránh tập trung vào

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 trong Python như một cách xác định hàm ngắn hơn

Python không khuyến khích sử dụng các biểu thức lambda được gọi ngay lập tức. Nó chỉ đơn giản là kết quả của một biểu thức lambda có thể gọi được, không giống như phần thân của một hàm bình thường

Các hàm lambda thường được sử dụng với các hàm bậc cao hơn, lấy một hoặc nhiều hàm làm đối số hoặc trả về một hoặc nhiều hàm

Hàm lambda có thể là hàm bậc cao hơn bằng cách lấy một hàm [bình thường hoặc lambda] làm đối số như trong ví dụ giả định sau

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
2

Python hiển thị các hàm bậc cao hơn dưới dạng các hàm tích hợp sẵn hoặc trong thư viện chuẩn. Các ví dụ bao gồm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
03, cũng như các chức năng chính như
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
04,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
05,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
06 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
07. Bạn sẽ sử dụng các hàm lambda cùng với các hàm bậc cao hơn của Python trong phần Sử dụng biểu thức Lambda phù hợp

Python Lambda và các hàm thông thường

Trích dẫn này từ Câu hỏi thường gặp về Lịch sử và Thiết kế Python dường như đặt ra âm thanh về kỳ vọng chung liên quan đến việc sử dụng các hàm lambda trong Python

Không giống như các biểu mẫu lambda trong các ngôn ngữ khác, nơi chúng thêm chức năng, lambdas Python chỉ là một ký hiệu viết tắt nếu bạn quá lười để xác định một hàm. [Nguồn]

Tuy nhiên, đừng để tuyên bố này ngăn cản bạn sử dụng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 của Python. Thoạt nhìn, bạn có thể chấp nhận rằng hàm lambda là một hàm có một số đường cú pháp rút ngắn mã để xác định hoặc gọi một hàm. Các phần sau đây nêu bật những điểm tương đồng và khác biệt tinh tế giữa các hàm Python bình thường và hàm lambda

Chức năng

Tại thời điểm này, bạn có thể thắc mắc về cơ bản điều gì phân biệt một hàm lambda được liên kết với một biến với một hàm thông thường có một dòng

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
09. dưới bề mặt, hầu như không có gì. Hãy xác minh cách Python nhìn thấy một hàm được xây dựng bằng một câu lệnh trả về duy nhất so với một hàm được xây dựng dưới dạng một biểu thức [
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79]

Mô-đun

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
11 hiển thị các hàm để phân tích mã byte Python do trình biên dịch Python tạo ra

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
3

Bạn có thể thấy rằng

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
12 hiển thị một phiên bản có thể đọc được của mã byte Python cho phép kiểm tra các hướng dẫn cấp thấp mà trình thông dịch Python sẽ sử dụng trong khi thực thi chương trình

Bây giờ hãy xem nó với một đối tượng chức năng thông thường

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
4

Mã byte được giải thích bởi Python giống nhau cho cả hai chức năng. Nhưng bạn có thể nhận thấy rằng cách đặt tên khác. tên hàm là

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
13 cho một hàm được xác định bằng
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
10, trong khi hàm lambda Python được xem là
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79

Tìm lại

Bạn đã thấy trong phần trước rằng, trong ngữ cảnh của hàm lambda, Python không cung cấp tên của hàm, mà chỉ cung cấp tên của hàm là

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
16. Đây có thể là một hạn chế cần xem xét khi xảy ra ngoại lệ và truy nguyên chỉ hiển thị
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
16

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
5

Truy nguyên của một ngoại lệ được đưa ra trong khi hàm lambda được thực thi chỉ xác định hàm gây ra ngoại lệ là

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
16

Đây là ngoại lệ tương tự được đưa ra bởi một chức năng bình thường

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
6

Hàm bình thường gây ra lỗi tương tự nhưng dẫn đến truy nguyên chính xác hơn vì nó cung cấp tên hàm,

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
19

cú pháp

Như bạn đã thấy trong các phần trước, biểu mẫu lambda thể hiện sự khác biệt về cú pháp với một hàm thông thường. Cụ thể, một hàm lambda có các đặc điểm sau

  • Nó chỉ có thể chứa các biểu thức và không thể bao gồm các câu lệnh trong phần thân của nó
  • Nó được viết dưới dạng một dòng thực thi
  • Nó không hỗ trợ chú thích loại
  • Nó có thể được gọi ngay lập tức [IIFE]

không có báo cáo

Hàm lambda không được chứa bất kỳ câu lệnh nào. Trong một hàm lambda, các câu lệnh như

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
09,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
21,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
22 hoặc
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
23 sẽ đưa ra một ngoại lệ
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
24. Đây là một ví dụ về việc thêm
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
22 vào phần thân của lambda

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
7

Ví dụ giả định này nhằm mục đích

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
22 rằng tham số
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 có giá trị là
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
18. Tuy nhiên, trình thông dịch xác định một
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
24 trong khi phân tích cú pháp mã liên quan đến câu lệnh
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
22 trong phần thân của
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79

Biểu thức đơn

Ngược lại với một hàm thông thường, hàm lambda trong Python là một biểu thức đơn. Mặc dù, trong phần nội dung của

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, bạn có thể trải biểu thức ra nhiều dòng bằng cách sử dụng dấu ngoặc đơn hoặc chuỗi nhiều dòng, nó vẫn là một biểu thức duy nhất

>>>

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
8

Ví dụ trên trả về chuỗi

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
33 khi đối số lambda là số lẻ và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
34 khi đối số là số chẵn. Nó trải rộng trên hai dòng bởi vì nó được chứa trong một tập hợp các dấu ngoặc đơn, nhưng nó vẫn là một biểu thức duy nhất

Loại chú thích

Nếu bạn đã bắt đầu áp dụng gợi ý kiểu, hiện đã có trong Python, thì bạn có một lý do chính đáng khác để thích các hàm bình thường hơn các hàm lambda của Python. Xem Kiểm tra loại Python [Hướng dẫn] để tìm hiểu thêm về gợi ý loại Python và kiểm tra loại. Trong một hàm lambda, không có tương đương với những điều sau đây

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
9

Bất kỳ lỗi loại nào với

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
35 đều có thể được phát hiện bằng các công cụ như
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
36 hoặc
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
37, trong khi một
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
24 có hàm lambda tương đương được phát hiện khi chạy

>>>

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
0

Giống như cố gắng đưa một câu lệnh vào lambda, việc thêm chú thích loại ngay lập tức dẫn đến một

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
24 khi chạy

IIFE

Bạn đã thấy một số ví dụ về thực thi chức năng được gọi ngay lập tức

>>>

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
1

Ngoài trình thông dịch Python, tính năng này có lẽ không được sử dụng trong thực tế. Đó là hệ quả trực tiếp của hàm lambda có thể gọi được khi nó được định nghĩa. Ví dụ: điều này cho phép bạn chuyển định nghĩa của biểu thức lambda Python sang một hàm bậc cao hơn như

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77 hoặc
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
03 hoặc một hàm chính

Tranh luận

Giống như một đối tượng hàm bình thường được định nghĩa bằng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
10, các biểu thức lambda Python hỗ trợ tất cả các cách truyền đối số khác nhau. Điêu nay bao gôm

  • đối số vị trí
  • Đối số được đặt tên [đôi khi được gọi là đối số từ khóa]
  • Danh sách biến đối số [thường được gọi là varargs]
  • Danh sách biến của các đối số từ khóa
  • Đối số chỉ từ khóa

Các ví dụ sau minh họa các tùy chọn mở cho bạn để chuyển đối số cho biểu thức lambda

>>>

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
2

người trang trí

Trong Python, một trình trang trí là việc triển khai một mẫu cho phép thêm một hành vi vào một hàm hoặc một lớp. Nó thường được thể hiện bằng cú pháp

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
44 tiền tố một hàm. Đây là một ví dụ giả tạo

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
3

Trong ví dụ trên,

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
45 là một hàm bổ sung một hành vi cho
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
46, để việc gọi
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
47 dẫn đến đầu ra sau

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
4

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
46 chỉ in
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
49, nhưng trình trang trí thêm một hành vi bổ sung cũng in
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
50

Một trang trí có thể được áp dụng cho lambda. Mặc dù không thể trang trí lambda bằng cú pháp

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
44, nhưng trình trang trí chỉ là một hàm, vì vậy nó có thể gọi hàm lambda

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
5

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
52, được trang trí bằng
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
53 trên dòng 11, được gọi với đối số
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
68 trên dòng 15. Ngược lại, ở dòng 18, một hàm lambda ngay lập tức được nhúng vào một lệnh gọi tới
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
55, trình trang trí. Khi bạn thực thi đoạn mã trên, bạn sẽ nhận được thông tin sau

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
6

Xem cách, như bạn đã thấy, tên của hàm lambda xuất hiện dưới dạng

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
16, trong khi
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
57 được xác định rõ ràng cho hàm thông thường

Trang trí hàm lambda theo cách này có thể hữu ích cho mục đích gỡ lỗi, có thể để gỡ lỗi hành vi của hàm lambda được sử dụng trong ngữ cảnh của hàm bậc cao hơn hoặc hàm chính. Hãy xem một ví dụ với

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
7

Đối số đầu tiên của

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 là một lambda nhân đối số của nó với
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
18. Lambda này được trang trí bằng
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
55. Khi được thực thi, ví dụ trên xuất ra kết quả như sau

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
8

Kết quả

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
62 là một danh sách thu được từ việc nhân từng phần tử của
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
63. Hiện tại, hãy coi
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
63 tương đương với danh sách
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
65

Bạn sẽ được tiếp xúc với

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 chi tiết hơn trong Bản đồ

Lambda cũng có thể là một công cụ trang trí, nhưng nó không được khuyến khích. Nếu bạn thấy mình cần làm điều này, hãy tham khảo PEP 8, Đề xuất lập trình

Để biết thêm về trình trang trí Python, hãy xem Primer on Python Decorators

Khép kín

Bao đóng là một hàm trong đó mọi biến tự do, mọi thứ trừ tham số, được sử dụng trong hàm đó được liên kết với một giá trị cụ thể được xác định trong phạm vi kèm theo của hàm đó. Trên thực tế, các bao đóng xác định môi trường mà chúng chạy và do đó có thể được gọi từ bất kỳ đâu

Các khái niệm về lambda và bao đóng không nhất thiết phải liên quan với nhau, mặc dù các hàm lambda có thể đóng theo cách giống như các hàm thông thường cũng có thể đóng. Một số ngôn ngữ có cấu trúc đặc biệt để đóng hoặc lambda [ví dụ: Groovy với một khối mã ẩn danh làm đối tượng Đóng] hoặc biểu thức lambda [ví dụ: biểu thức Java Lambda với tùy chọn giới hạn để đóng]

Đây là một bao đóng được xây dựng bằng hàm Python bình thường

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
9

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 trả về
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
68, một hàm lồng nhau tính tổng của ba đối số

  • [lambda x: x + 1][2] = lambda 2: 2 + 1
                         = 2 + 1
                         = 3
    
    12 được truyền dưới dạng đối số cho
    class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    67
  • class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    71 là biến cục bộ của
    class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    67
  • class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    73 là một đối số được truyền cho
    class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    68

Để kiểm tra hành vi của

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
68,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 được gọi ba lần trong vòng lặp
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
78 in ra thông tin sau

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
0

Trên dòng 9 của mã,

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
68 được trả về bởi lời gọi của
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 bị ràng buộc với tên
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
81. Ở dòng 5,
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
68 nắm bắt
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
71 vì nó có quyền truy cập vào môi trường nhúng của nó, sao cho khi gọi hàm đóng, nó có thể hoạt động trên hai biến tự do
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
71

Tương tự, một

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 cũng có thể là một đóng cửa. Đây là ví dụ tương tự với hàm lambda Python

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
1

Khi bạn thực thi đoạn mã trên, bạn nhận được đầu ra sau

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
2

Ở dòng 6,

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 trả về một lambda và gán nó cho biến
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
81. Ở dòng 3, phần thân của hàm lambda tham chiếu đến
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
71. Biến
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
71 có sẵn tại thời điểm định nghĩa, trong khi đó,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
12 được xác định tại thời điểm chạy khi
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
67 được gọi

Trong tình huống này, cả chức năng bình thường và lambda đều hoạt động giống nhau. Trong phần tiếp theo, bạn sẽ thấy tình huống trong đó hành vi của lambda có thể bị đánh lừa do thời gian đánh giá của nó [thời gian xác định so với thời gian chạy]

Thời gian đánh giá

Trong một số tình huống liên quan đến vòng lặp, hành vi của hàm lambda Python dưới dạng bao đóng có thể phản trực giác. Nó đòi hỏi sự hiểu biết khi các biến miễn phí bị ràng buộc trong ngữ cảnh của lambda. Các ví dụ sau minh họa sự khác biệt khi sử dụng hàm thông thường so với sử dụng Python lambda

Kiểm tra kịch bản trước bằng cách sử dụng chức năng thông thường

>>>

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
3

Trong một hàm thông thường,

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi hàm được thêm vào danh sách.
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
96

Bây giờ, với việc triển khai logic tương tự với hàm lambda, hãy quan sát hành vi không mong muốn

>>>

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
4

Kết quả không mong muốn xảy ra do biến tự do

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95, khi được triển khai, bị ràng buộc tại thời điểm thực hiện biểu thức lambda. Hàm lambda của Python trên dòng 4 là một bao đóng bắt giữ
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95, một biến tự do bị ràng buộc trong thời gian chạy. Khi chạy, trong khi gọi hàm
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
99 trên dòng 7, giá trị của
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95 là
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
01

Để khắc phục vấn đề này, bạn có thể gán biến tự do tại thời điểm định nghĩa như sau

>>>

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
5

Một hàm lambda Python hoạt động giống như một hàm bình thường đối với các đối số. Do đó, một tham số lambda có thể được khởi tạo với giá trị mặc định. tham số

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95 lấy bên ngoài
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95 làm giá trị mặc định. Hàm lambda Python có thể đã được viết là
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
04 và có kết quả tương tự

Hàm lambda Python được gọi mà không có bất kỳ đối số nào trên dòng 7 và nó sử dụng giá trị mặc định

class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
95 được đặt tại thời điểm định nghĩa

Kiểm tra Lambda

Lambdas Python có thể được kiểm tra tương tự như các chức năng thông thường. Có thể sử dụng cả

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
06 và
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
07

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
06

Mô-đun

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
06 xử lý các hàm lambda Python tương tự như các hàm thông thường

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
6

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
10 định nghĩa một trường hợp thử nghiệm với ba phương pháp thử nghiệm, mỗi phương pháp thực hiện một kịch bản thử nghiệm cho
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
11 được triển khai dưới dạng hàm lambda. Việc thực thi tệp Python
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
12 chứa
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
10 tạo ra như sau

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
7

Như mong đợi, chúng tôi có hai trường hợp thử nghiệm thành công và một trường hợp thất bại cho

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
14. kết quả là
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
69, nhưng kết quả mong đợi là
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
16. Thất bại này là do lỗi cố ý trong trường hợp thử nghiệm. Thay đổi kết quả dự kiến ​​từ
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
16 thành
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
69 sẽ đáp ứng tất cả các bài kiểm tra cho
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
10

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
07

Mô-đun

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
07 trích xuất mã Python tương tác từ
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
22 để thực hiện kiểm tra. Mặc dù cú pháp của các hàm lambda Python không hỗ trợ một
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
22 điển hình, nhưng có thể gán một chuỗi cho phần tử
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
24 của một lambda có tên

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
8

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
07 trong doc comment của lambda
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
11 mô tả các trường hợp thử nghiệm giống như trong phần trước

Khi bạn thực hiện các bài kiểm tra qua

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
27, bạn sẽ nhận được thông tin sau

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
9

Kết quả kiểm tra thất bại từ lỗi tương tự được giải thích trong quá trình thực hiện kiểm tra đơn vị trong phần trước

Bạn có thể thêm một

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
22 vào một lambda Python thông qua một phép gán cho
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
24 để ghi lại một hàm lambda. Mặc dù có thể, nhưng cú pháp Python phù hợp hơn với
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
22 cho các hàm thông thường so với các hàm lambda

Để biết tổng quan toàn diện về thử nghiệm đơn vị trong Python, bạn có thể tham khảo Bắt đầu với thử nghiệm trong Python

Lạm dụng biểu hiện Lambda

Một số ví dụ trong bài viết này, nếu được viết trong ngữ cảnh mã Python chuyên nghiệp, sẽ bị coi là lạm dụng

Nếu bạn thấy mình đang cố khắc phục điều gì đó mà biểu thức lambda không hỗ trợ, đây có thể là dấu hiệu cho thấy một chức năng bình thường sẽ phù hợp hơn.

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
22 cho biểu thức lambda trong phần trước là một ví dụ điển hình. Cố gắng khắc phục thực tế là hàm lambda Python không hỗ trợ các câu lệnh là một dấu hiệu đỏ khác

Các phần tiếp theo minh họa một số ví dụ về cách sử dụng lambda nên tránh. Những ví dụ đó có thể là những tình huống trong ngữ cảnh của Python lambda, mã hiển thị mẫu sau

  • Nó không tuân theo hướng dẫn kiểu Python [PEP 8]
  • Nó rườm rà và khó đọc
  • Nó thông minh một cách không cần thiết với chi phí khó đọc

Tăng một ngoại lệ

Cố gắng đưa ra một ngoại lệ trong Python lambda sẽ khiến bạn phải suy nghĩ kỹ. Có một số cách thông minh để làm như vậy, nhưng ngay cả những cách như sau vẫn tốt hơn để tránh

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
20

Vì một câu lệnh không đúng về mặt cú pháp trong phần thân lambda của Python, nên cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa lệnh gọi câu lệnh bằng một hàm chuyên dụng

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
32. Nên tránh sử dụng loại giải pháp thay thế này. Nếu bạn gặp loại mã này, bạn nên xem xét cấu trúc lại mã để sử dụng một chức năng thông thường

Phong cách mật mã

Như trong bất kỳ ngôn ngữ lập trình nào, bạn sẽ thấy mã Python khó đọc do phong cách được sử dụng. Các hàm lambda, do tính ngắn gọn của chúng, có thể thuận lợi cho việc viết mã khó đọc

Ví dụ lambda sau đây chứa một số lựa chọn kiểu xấu

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
21

Dấu gạch dưới [

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
65] đề cập đến một biến mà bạn không cần phải đề cập đến một cách rõ ràng. Nhưng trong ví dụ này, ba
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
65 đề cập đến các biến khác nhau. Nâng cấp ban đầu cho mã lambda này có thể là đặt tên cho các biến

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
22

Phải thừa nhận rằng nó vẫn còn khó đọc. Bằng cách vẫn tận dụng một

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, một chức năng thông thường sẽ đi một chặng đường dài để làm cho mã này dễ đọc hơn, trải rộng logic trên một vài dòng và lệnh gọi hàm

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
23

Điều này vẫn chưa tối ưu nhưng cho bạn thấy một đường dẫn khả thi để tạo mã và đặc biệt là các hàm lambda của Python, dễ đọc hơn. Trong Các lựa chọn thay thế cho Lambdas, bạn sẽ học cách thay thế

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 và
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 bằng cách hiểu danh sách hoặc biểu thức trình tạo. Điều này sẽ cải thiện đáng kể khả năng đọc mã

Lớp học Python

Bạn có thể nhưng không nên viết các phương thức lớp dưới dạng các hàm lambda Python. Ví dụ sau đây là mã Python hoàn toàn hợp pháp nhưng hiển thị mã Python độc đáo dựa trên

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79. Ví dụ: thay vì triển khai
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
39 như một chức năng thông thường, nó sử dụng một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79. Tương tự,
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
41 và
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
42 là các thuộc tính cũng được triển khai với các hàm lambda, thay vì các hàm hoặc trình trang trí thông thường

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
24

Chạy một công cụ như

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
43, một công cụ thực thi hướng dẫn kiểu, sẽ hiển thị các lỗi sau cho
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
39 và
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
45

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
25

Mặc dù

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
43 không chỉ ra vấn đề đối với việc sử dụng các hàm lambda Python trong các thuộc tính, nhưng chúng rất khó đọc và dễ bị lỗi do sử dụng nhiều chuỗi như
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
47 và
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
48

Việc thực hiện đúng

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
39 sẽ được mong đợi như sau

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
26

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
41 sẽ được viết như sau

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
27

Theo nguyên tắc chung, trong ngữ cảnh mã được viết bằng Python, hãy ưu tiên các hàm thông thường hơn biểu thức lambda. Tuy nhiên, có những trường hợp được hưởng lợi từ cú pháp lambda, như bạn sẽ thấy trong phần tiếp theo

Sử dụng thích hợp các biểu thức Lambda

Lambdas trong Python có xu hướng trở thành chủ đề gây tranh cãi. Một số đối số chống lại lambdas trong Python là

  • Các vấn đề về khả năng đọc
  • Việc áp đặt một cách suy nghĩ chức năng
  • Cú pháp nặng với từ khóa
    [lambda x: x + 1][2] = lambda 2: 2 + 1
                         = 2 + 1
                         = 3
    
    79

Bất chấp các cuộc tranh luận sôi nổi đặt câu hỏi về sự tồn tại đơn thuần của tính năng này trong Python, các hàm lambda có các thuộc tính đôi khi cung cấp giá trị cho ngôn ngữ Python và cho các nhà phát triển

Các ví dụ sau minh họa các tình huống trong đó việc sử dụng các hàm lambda không chỉ phù hợp mà còn được khuyến khích trong mã Python

Cấu trúc chức năng cổ điển

Các hàm lambda thường được sử dụng với các hàm tích hợp sẵn

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 và
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77, cũng như
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
03, được hiển thị trong mô-đun
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
55. Ba ví dụ sau đây là minh họa tương ứng về việc sử dụng các hàm đó với các biểu thức lambda làm bạn đồng hành

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
28

Bạn có thể phải đọc mã giống như các ví dụ trên, mặc dù có nhiều dữ liệu phù hợp hơn. Vì lý do đó, điều quan trọng là phải nhận ra những cấu trúc đó. Tuy nhiên, những cấu trúc đó có các lựa chọn thay thế tương đương được coi là Pythonic hơn. Trong Các lựa chọn thay thế cho Lambda, bạn sẽ tìm hiểu cách chuyển đổi các hàm bậc cao hơn và các lambda đi kèm của chúng thành các dạng thành ngữ khác

Chức năng chính

Các hàm chính trong Python là các hàm bậc cao lấy tham số

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
56 làm đối số được đặt tên.
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
56 nhận một chức năng có thể là một
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79. Chức năng này ảnh hưởng trực tiếp đến thuật toán do chính chức năng chính điều khiển. Dưới đây là một số chức năng chính

  • class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    04. phương pháp liệt kê
  • class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    05,
    class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    06,
    class MyClass:
        my_attr = False
        def __init__[self, value]:
            self.value = value
    myinstance = MyClass[25]
    
    x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
    short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
    # ^^^ this one works only for MyClass' attributes.
    
    print[MyClass.my_attr] # output: False
    x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
    print[MyClass.my_attr] # output: True
    x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
    print[MyClass.my_attr2] # output: 5
    short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
    print[MyClass.my_attr2] # output: 123
    
    print[myinstance.value] # output: 25
    x[myinstance, 'value', 500]
    print[myinstance.value] # output: 500
    
    07. Chức năng tích hợp sẵn
  • class Value:
        def __init__[self, value]:
            self.value = value
    
    x = lambda var, newvalue: setattr[var, 'value', newvalue]
    
    a = Value[15]
    print[a.value] # output: 15
    x[a, 25]
    print[a.value] # output: 25
    
    63 và
    class Value:
        def __init__[self, value]:
            self.value = value
    
    x = lambda var, newvalue: setattr[var, 'value', newvalue]
    
    a = Value[15]
    print[a.value] # output: 15
    x[a, 25]
    print[a.value] # output: 25
    
    64. trong mô-đun thuật toán hàng đợi Heap
    class Value:
        def __init__[self, value]:
            self.value = value
    
    x = lambda var, newvalue: setattr[var, 'value', newvalue]
    
    a = Value[15]
    print[a.value] # output: 15
    x[a, 25]
    print[a.value] # output: 25
    
    65

Hãy tưởng tượng rằng bạn muốn sắp xếp danh sách ID được biểu thị dưới dạng chuỗi. Mỗi ID là phần nối của chuỗi

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
66 và một số. Sắp xếp danh sách này bằng hàm tích hợp sẵn
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
05, theo mặc định, sử dụng thứ tự từ điển vì các phần tử trong danh sách là các chuỗi

Để tác động đến việc thực thi sắp xếp, bạn có thể gán lambda cho đối số có tên là

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
56, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
29

Khung giao diện người dùng

Các khung giao diện người dùng như Tkinter, wxPython hoặc. NET Windows Forms với IronPython tận dụng các chức năng lambda để ánh xạ các hành động để đáp ứng với các sự kiện giao diện người dùng

Chương trình Tkinter ngây thơ dưới đây minh họa việc sử dụng một

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 được gán cho lệnh của nút Đảo ngược

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
90

Nhấp vào nút Đảo ngược kích hoạt một sự kiện kích hoạt hàm lambda, thay đổi nhãn từ Lambda Calculus thành suluclaC adbmaL*

Cả wxPython và IronPython trên. NET chia sẻ một cách tiếp cận tương tự để xử lý các sự kiện. Lưu ý rằng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 là một cách để xử lý các sự kiện kích hoạt, nhưng một chức năng có thể được sử dụng cho cùng một mục đích. Cuối cùng, việc sử dụng
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 trở nên khép kín và ít dài dòng hơn khi lượng mã cần thiết rất ngắn

Để khám phá wxPython, hãy xem Cách xây dựng ứng dụng GUI Python với wxPython

Trình thông dịch Python

Khi bạn đang chơi với mã Python trong trình thông dịch tương tác, các hàm lambda của Python thường là một điều may mắn. Thật dễ dàng để tạo một chức năng một lớp lót nhanh chóng để khám phá một số đoạn mã sẽ không bao giờ nhìn thấy ánh sáng ban ngày bên ngoài trình thông dịch. Lambdas được viết trong trình thông dịch, để khám phá nhanh chóng, giống như giấy vụn mà bạn có thể vứt đi sau khi sử dụng

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
72

Theo tinh thần giống như thử nghiệm trong trình thông dịch Python, mô-đun

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
72 cung cấp các hàm tính thời gian cho các đoạn mã nhỏ.
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
74 nói riêng có thể được gọi trực tiếp, chuyển một số mã Python trong một chuỗi. Đây là một ví dụ

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
91

Khi câu lệnh được truyền dưới dạng chuỗi,

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
75 cần có ngữ cảnh đầy đủ. Trong ví dụ trên, điều này được cung cấp bởi đối số thứ hai thiết lập môi trường cần thiết cho chức năng chính được tính thời gian. Không làm như vậy sẽ gây ra một ngoại lệ
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
76

Một cách tiếp cận khác là sử dụng một

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
92

Giải pháp này sạch hơn, dễ đọc hơn và nhập trình thông dịch nhanh hơn. Mặc dù thời gian thực hiện ít hơn một chút đối với phiên bản

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, nhưng việc thực hiện lại các chức năng có thể cho thấy một chút lợi thế đối với phiên bản
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
79. Thời gian thực hiện của
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
80 được loại trừ khỏi thời gian thực hiện tổng thể và không có bất kỳ tác động nào đến kết quả

khỉ vá

Để thử nghiệm, đôi khi cần phải dựa vào các kết quả có thể lặp lại, ngay cả khi trong quá trình thực thi bình thường của một phần mềm nhất định, các kết quả tương ứng dự kiến ​​sẽ khác nhau hoặc thậm chí là hoàn toàn ngẫu nhiên

Giả sử bạn muốn kiểm tra một chức năng, trong thời gian chạy, xử lý các giá trị ngẫu nhiên. Tuy nhiên, trong quá trình thực hiện thử nghiệm, bạn cần xác nhận các giá trị có thể dự đoán theo cách có thể lặp lại. Ví dụ sau đây cho thấy cách, với hàm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, bản vá khỉ có thể giúp bạn

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
93

Trình quản lý ngữ cảnh giúp cách ly hoạt động của khỉ vá một hàm từ thư viện chuẩn [

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
82, trong ví dụ này]. Hàm lambda được gán cho
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
83 thay thế hành vi mặc định bằng cách trả về một giá trị tĩnh

Điều này cho phép kiểm tra bất kỳ chức năng nào tùy thuộc vào

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
84 theo cách có thể dự đoán được. Trước khi thoát khỏi trình quản lý bối cảnh, hành vi mặc định của
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
84 được thiết lập lại để loại bỏ bất kỳ tác dụng phụ không mong muốn nào có thể ảnh hưởng đến các khu vực khác của thử nghiệm có thể phụ thuộc vào hành vi mặc định của
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
84

Các khung kiểm tra đơn vị như

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
06 và
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
88 đưa khái niệm này lên một mức độ phức tạp cao hơn

Với

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
88, vẫn sử dụng hàm
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, ví dụ tương tự trở nên thanh lịch và ngắn gọn hơn

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
94

Với vật cố định pytest

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
91,
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
83 được ghi đè bằng lambda sẽ trả về một giá trị xác định,
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
93, cho phép xác thực thử nghiệm. Vật cố định pytest
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
91 cho phép bạn kiểm soát phạm vi ghi đè. Trong ví dụ trên, việc gọi
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
83 trong các thử nghiệm tiếp theo, mà không sử dụng bản vá khỉ, sẽ thực thi chức năng này bình thường

Thực hiện kiểm tra

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
88 cho kết quả sau

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
95

Thử nghiệm vượt qua khi chúng tôi xác nhận rằng

class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
97 đã được thực hiện và kết quả là kết quả mong đợi trong bối cảnh thử nghiệm

Các lựa chọn thay thế cho Lambda

Mặc dù có những lý do tuyệt vời để sử dụng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, nhưng vẫn có những trường hợp việc sử dụng nó bị phản đối. Vì vậy, các lựa chọn thay thế là gì?

Các hàm bậc cao hơn như

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77 và
class MyClass:
    my_attr = False
    def __init__[self, value]:
        self.value = value
myinstance = MyClass[25]

x = lambda obj, nameofvar, value: setattr[obj, nameofvar, value]
short_x = lambda nameofvar, value: setattr[MyClass, nameofvar, value]
# ^^^ this one works only for MyClass' attributes.

print[MyClass.my_attr] # output: False
x[MyClass, 'my_attr', True] # Changing MyClass' my_attr's value
print[MyClass.my_attr] # output: True
x[MyClass, 'my_attr2', 5] # Assigning new attribute to MyClass
print[MyClass.my_attr2] # output: 5
short_x['my_attr2', 123] # Setting MyClass' my_attr2 to 123
print[MyClass.my_attr2] # output: 123

print[myinstance.value] # output: 25
x[myinstance, 'value', 500]
print[myinstance.value] # output: 500
03 có thể được chuyển đổi thành các dạng thanh lịch hơn với một chút sáng tạo, đặc biệt là với khả năng hiểu danh sách hoặc biểu thức trình tạo

Để tìm hiểu thêm về cách hiểu danh sách, hãy xem Khi nào nên sử dụng cách hiểu danh sách trong Python. Để tìm hiểu thêm về các biểu thức trình tạo, hãy xem Cách sử dụng Trình tạo và năng suất trong Python

Bản đồ

Hàm dựng sẵn

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 lấy một hàm làm đối số đầu tiên và áp dụng nó cho từng phần tử của đối số thứ hai, một hàm có thể lặp lại. Ví dụ về iterables là chuỗi, danh sách và bộ dữ liệu. Để biết thêm thông tin về iterables và iterators, hãy xem Iterables và Iterators

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 trả về một trình vòng lặp tương ứng với bộ sưu tập được chuyển đổi. Ví dụ: nếu bạn muốn chuyển đổi danh sách chuỗi thành danh sách mới với mỗi chuỗi được viết hoa, bạn có thể sử dụng
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76, như sau

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
96

Bạn cần gọi

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
05 để chuyển đổi trình vòng lặp được trả về bởi
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 thành một danh sách mở rộng có thể được hiển thị trong trình thông dịch trình bao Python

Sử dụng khả năng hiểu danh sách giúp loại bỏ nhu cầu xác định và gọi hàm lambda

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
97

Lọc

Hàm dựng sẵn

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77, một cấu trúc hàm cổ điển khác, có thể được chuyển thành dạng hiểu danh sách. Nó lấy một biến vị ngữ làm đối số đầu tiên và một biến lặp lại làm đối số thứ hai. Nó xây dựng một iterator chứa tất cả các phần tử của tập hợp ban đầu thỏa mãn chức năng vị ngữ. Đây là một ví dụ lọc tất cả các số chẵn trong một danh sách các số nguyên đã cho

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
98

Lưu ý rằng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77 trả về một trình vòng lặp, do đó cần phải gọi loại tích hợp sẵn
lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
09 để xây dựng một danh sách được cung cấp một trình vòng lặp

Việc triển khai tận dụng cấu trúc hiểu danh sách đưa ra những điều sau đây

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
99

Giảm

Kể từ Python 3,

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
78 đã chuyển từ chức năng tích hợp sang chức năng mô-đun
class Value:
    def __init__[self, value]:
        self.value = value

x = lambda var, newvalue: setattr[var, 'value', newvalue]

a = Value[15]
print[a.value] # output: 15
x[a, 25]
print[a.value] # output: 25
55. Là
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
76 và
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
77, hai đối số đầu tiên của nó lần lượt là một hàm và một hàm lặp. Nó cũng có thể lấy một bộ khởi tạo làm đối số thứ ba được sử dụng làm giá trị ban đầu của bộ tích lũy kết quả. Đối với mỗi phần tử của iterable,
[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
78 áp dụng hàm và tích lũy kết quả được trả về khi iterable cạn kiệt

Để áp dụng

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
78 cho một danh sách các cặp và tính tổng của phần tử đầu tiên của mỗi cặp, bạn có thể viết

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
0

Một cách tiếp cận thành ngữ hơn bằng cách sử dụng biểu thức trình tạo, làm đối số cho

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
16 trong ví dụ, như sau

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
1

Một giải pháp hơi khác và có thể sạch hơn sẽ loại bỏ nhu cầu truy cập rõ ràng vào phần tử đầu tiên của cặp và thay vào đó sử dụng giải nén

>>>

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
2

Việc sử dụng dấu gạch dưới [

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
65] là một quy ước Python cho biết rằng bạn có thể bỏ qua giá trị thứ hai của cặp

lst = [15, 30, 45, 60, 75, 90]

x = lambda iterable, item, value: iterable.__setitem__[item, value]

print[lst] # output: [15, 30, 45, 60, 75, 90]
x[lst, 2, 1000]
print[lst] # output: [15, 30, 1000, 60, 75, 90]
16 lấy một đối số duy nhất, vì vậy biểu thức trình tạo không cần phải nằm trong dấu ngoặc đơn

Lambdas có phải Pythonic hay không?

PEP 8, là hướng dẫn phong cách cho mã Python, đọc

Luôn sử dụng câu lệnh def thay vì câu lệnh gán liên kết trực tiếp biểu thức lambda với mã định danh. [Nguồn]

Điều này hoàn toàn không khuyến khích sử dụng lambda được liên kết với một mã định danh, chủ yếu là nơi các chức năng nên được sử dụng và có nhiều lợi ích hơn. PEP 8 không đề cập đến các cách sử dụng khác của

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79. Như bạn đã thấy trong các phần trước, các hàm lambda chắc chắn có thể có những công dụng tốt, mặc dù chúng bị hạn chế.

Một cách có thể để trả lời câu hỏi là các hàm lambda hoàn toàn là Pythonic nếu không có gì Pythonic khả dụng hơn. Tôi đang tránh xa việc định nghĩa “Pythonic” nghĩa là gì, để lại cho bạn định nghĩa phù hợp nhất với suy nghĩ của bạn, cũng như phong cách viết mã của cá nhân bạn hoặc nhóm của bạn

Ngoài phạm vi hẹp của Python

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79, Cách viết mã Python đẹp bằng PEP 8 là một tài nguyên tuyệt vời mà bạn có thể muốn xem về kiểu mã trong Python

Sự kết luận

Bây giờ bạn đã biết cách sử dụng các hàm

[lambda x: x + 1][2] = lambda 2: 2 + 1
                     = 2 + 1
                     = 3
79 của Python và có thể

  • Viết Python lambdas và sử dụng các chức năng ẩn danh
  • Chọn một cách khôn ngoan giữa lambdas hoặc các hàm Python bình thường
  • Tránh sử dụng quá nhiều lambdas
  • Sử dụng lambdas với các hàm bậc cao hơn hoặc các hàm chính của Python

Nếu bạn có thiên hướng về toán học, bạn có thể có một số niềm vui khi khám phá thế giới hấp dẫn của phép tính lambda

Python lambdas giống như muối. Một nhúm nhỏ trong thư rác, giăm bông và trứng của bạn sẽ làm tăng hương vị, nhưng quá nhiều sẽ làm hỏng món ăn

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Cách sử dụng các hàm Lambda của Python

Làm thế nào để bạn khai báo một biến trong lambda?

Biến được xác định bởi phạm vi kèm theo của biểu thức lambda có thể truy cập được trong biểu thức lambda

Chủ Đề