Các hàm là một trong những "công dân hạng nhất" của Python, có nghĩa là các hàm ở cùng cấp độ với các đối tượng Python khác như số nguyên, chuỗi, mô-đun, v.v. Chúng có thể được tạo và hủy một cách linh hoạt, được chuyển đến các hàm khác, được trả về dưới dạng giá trị, v.v.
Python hỗ trợ khái niệm "hàm lồng nhau" hoặc "hàm bên trong", đơn giản là một hàm được định nghĩa bên trong một hàm khác. Trong phần còn lại của bài viết, chúng ta sẽ sử dụng thay thế cho từ "hàm bên trong" và "hàm lồng nhau"
Có nhiều lý do giải thích tại sao người ta muốn tạo một chức năng bên trong một chức năng khác. Hàm bên trong có thể truy cập các biến trong phạm vi kèm theo. Trong bài viết này, chúng ta sẽ khám phá các khía cạnh khác nhau của các hàm bên trong Python
Xác định một chức năng bên trong
Để xác định một hàm bên trong Python, chúng ta chỉ cần tạo một hàm bên trong một hàm khác bằng cách sử dụng từ khóa
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
5 của Python. Đây là một ví dụđầu ra
Hello from outer function
Hello from inner function
Trong ví dụ trên,
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
0 đã được xác định bên trong def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
1, khiến nó trở thành một hàm bên trong. Để gọi def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
0, trước tiên chúng ta phải gọi def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
1. Sau đó, def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
1 sẽ tiếp tục và gọi def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
0 vì nó đã được xác định bên trong nóĐiều quan trọng cần đề cập là chức năng bên ngoài phải được gọi để chức năng bên trong thực thi. Nếu chức năng bên ngoài không được gọi, chức năng bên trong sẽ không bao giờ thực thi. Để chứng minh điều này, hãy sửa đổi đoạn mã trên thành đoạn mã sau và chạy nó
Mã sẽ không trả lại gì khi được thực thi
Đây là một ví dụ khác
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
đầu ra
________số 8Mã trả về phép nhân của hai số, nghĩa là 10 và 5. Ví dụ cho thấy một hàm bên trong có thể truy cập các biến có thể truy cập trong hàm bên ngoài
Đến đây, bạn đã thấy rằng chúng ta có thể truy cập các biến của hàm bên ngoài bên trong hàm bên trong. Điều gì sẽ xảy ra nếu chúng ta cố gắng thay đổi các biến của hàm bên ngoài từ bên trong hàm bên trong?
đầu ra
2
9
Đầu ra cho thấy rằng chúng ta có thể hiển thị giá trị của một biến được xác định trong hàm bên ngoài từ hàm bên trong, nhưng không thể thay đổi nó. Câu lệnh
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
6 đã giúp chúng ta tạo một biến mới def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
7 bên trong hàm bên trong def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
0 thay vì thay đổi giá trị của biến def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
7 được xác định trong hàm bên ngoài def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
1Trong phần tiếp theo, chúng ta sẽ thảo luận về những lý do chính tại sao chúng ta sử dụng các hàm bên trong Python
Tại sao nên sử dụng Hàm bên trong?
đóng gói
Một chức năng có thể được tạo như một chức năng bên trong để bảo vệ nó khỏi mọi thứ đang xảy ra bên ngoài chức năng. Trong trường hợp đó, chức năng sẽ bị ẩn khỏi phạm vi toàn cầu. Đây là một ví dụ
Hãy xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, tiêu chuẩn được ngành chấp nhận và bao gồm bảng gian lận. Dừng các lệnh Git trên Google và thực sự tìm hiểu nó
đầu ra
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
5Trong đoạn mã trên, chúng tôi đang cố gắng gọi hàm
50
1, nhưng thay vào đó chúng tôi gặp lỗiBây giờ, hãy ghi chú cuộc gọi tới
50
1 và bỏ ghi chú cuộc gọi tới 50
3 như hình bên dướiđầu ra
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
9Đoạn script trên cho thấy rằng hàm bên trong, tức là,
50
1 được bảo vệ khỏi những gì đang xảy ra bên ngoài vì biến def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
7 bên trong hàm 50
6 không bị ảnh hưởng bởi giá trị được truyền cho tham số def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
7 của hàm bên ngoài. Nói cách khác, các biến bên trong hàm bên trong không thể truy cập bên ngoài nó. Có một lợi thế lớn với một mẫu thiết kế như vậy. Sau khi kiểm tra tất cả các đối số trong hàm bên ngoài, chúng ta có thể bỏ qua việc kiểm tra lỗi trong hàm bên trong một cách an toànChức năng đóng cửa và nhà máy
Tất cả các ví dụ chúng ta đã thấy cho đến bây giờ chỉ chứa các hàm thông thường đã được lồng vào bên trong các hàm khác. Chúng ta có thể viết các hàm như vậy theo cách khác thay vì lồng chúng vào bên trong các hàm khác. Chúng tôi không có lý do cụ thể là tại sao chúng tôi nên lồng chúng vào nhau
Tuy nhiên, đối với trường hợp bao đóng, người ta phải sử dụng các hàm lồng nhau
Chúng ta có thể liên kết/truyền dữ liệu cho một hàm mà không nhất thiết phải truyền dữ liệu cho hàm thông qua các tham số. Điều này được thực hiện bằng cách sử dụng một bao đóng. Nó là một đối tượng chức năng có thể nhớ các giá trị trong phạm vi kèm theo ngay cả khi chúng không có sẵn trong bộ nhớ. Điều này có nghĩa là chúng ta có một bao đóng khi một hàm lồng nhau tham chiếu đến một giá trị nằm trong phạm vi bao quanh của nó
Mục đích của bao đóng là làm cho hàm bên trong ghi nhớ trạng thái của môi trường khi nó được gọi, ngay cả khi nó không có trong bộ nhớ. Một đóng cửa được gây ra bởi một chức năng bên trong, nhưng nó không phải là chức năng bên trong. Việc đóng hoạt động bằng cách đóng biến cục bộ trên ngăn xếp, biến này sẽ tồn tại sau khi quá trình tạo ngăn xếp kết thúc
Sau đây là các điều kiện bắt buộc phải đáp ứng để tạo bao đóng trong Python
- Phải có một chức năng lồng nhau
- Hàm bên trong phải tham chiếu đến một giá trị được xác định trong phạm vi kèm theo
- Hàm kèm theo phải trả về hàm lồng nhau
Xem xét ví dụ sau
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
4đầu ra
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
5Đoạn mã trên chứng minh rằng với bao đóng, chúng ta có thể tạo và gọi một hàm từ bên ngoài phạm vi của nó thông qua hàm truyền. Phạm vi của
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
0 chỉ bên trong def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
1. Tuy nhiên, với việc sử dụng các bao đóng, chúng tôi có thể mở rộng phạm vi này và gọi nó từ bên ngoài phạm vi của nóCác hàm bên trong giúp chúng ta xác định các hàm của nhà máy. Hàm xuất xưởng là hàm tạo một đối tượng khác. Ví dụ
đầu ra
def num1[x]:
def num2[y]:
return x * y
return num2
res = num1[10]
print[res[5]]
8Trong đoạn script trên, từ hàm
2
9
0, chúng ta đã tạo thêm 2 đối tượng khác là 2
9
1 và 2
9
2. Điều này làm cho 2
9
0 trở thành một hàm xuất xưởng vì nó tạo ra các hàm 2
9
1 và 2
9
2 cho chúng ta bằng cách sử dụng tham số mà chúng ta truyền cho nóSự kết luận
Một hàm bên trong chỉ đơn giản là một hàm được định nghĩa bên trong một hàm khác. Hàm bên trong có thể truy cập các biến đã được xác định trong phạm vi của hàm bên ngoài, nhưng nó không thể thay đổi chúng. Có một số lý do là tại sao chúng ta có thể cần tạo một hàm bên trong. Chẳng hạn, một chức năng bên trong được bảo vệ khỏi những gì xảy ra bên ngoài nó. Các hàm bên trong cũng là một cách hay để tạo các bao đóng trong Python