Hướng dẫn can you call a function inside a function in python? - bạn có thể gọi một hàm bên trong một hàm trong python không?

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để làm sâu sắc thêm sự hiểu biết của bạn: các chức năng bên trong của Python This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Python Inner Functions

Show

Các chức năng bên trong, còn được gọi là các hàm lồng nhau, là các hàm mà bạn xác định bên trong các chức năng khác. Trong Python, loại chức năng này có quyền truy cập trực tiếp vào các biến và tên được xác định trong hàm kèm theo. Các chức năng bên trong có nhiều cách sử dụng, đáng chú ý nhất là các nhà máy đóng cửa và chức năng trang trí., also known as nested functions, are functions that you define inside other functions. In Python, this kind of function has direct access to variables and names defined in the enclosing function. Inner functions have many uses, most notably as closure factories and decorator functions.

Trong hướng dẫn này, bạn sẽ học cách:

  • Cung cấp đóng gói và ẩn các chức năng của bạn khỏi quyền truy cập bên ngoàiencapsulation and hide your functions from external access
  • Viết các chức năng của người trợ giúp để tạo điều kiện tái sử dụng mãhelper functions to facilitate code reuse
  • Tạo các chức năng của nhà máy đóng cửa giữ trạng thái giữa các cuộc gọiclosure factory functions that retain state between calls
  • Chức năng trang trí mã để thêm hành vi vào các chức năng hiện códecorator functions to add behavior to existing functions

Tạo các chức năng bên trong Python

Một hàm được xác định bên trong một hàm khác được gọi là hàm bên trong hoặc hàm lồng nhau. Trong Python, loại chức năng này có thể truy cập tên trong hàm kèm theo. Ở đây, một ví dụ về cách tạo chức năng bên trong trong Python:inner function or a nested function. In Python, this kind of function can access names in the enclosing function. Here’s an example of how to create an inner function in Python:

>>>

>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!

Trong mã này, bạn xác định

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 bên trong
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7 để in thông báo
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8 lên màn hình. Để làm điều đó, bạn gọi
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 trên dòng cuối cùng của
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7. Đây là cách nhanh nhất để viết một chức năng bên trong trong Python. Tuy nhiên, các chức năng bên trong cung cấp rất nhiều khả năng thú vị ngoài những gì bạn thấy trong ví dụ này.

Tính năng cốt lõi của các hàm bên trong là khả năng truy cập các biến và đối tượng từ chức năng kèm theo của chúng ngay cả sau khi chức năng này đã trở lại. Hàm kèm theo cung cấp một không gian tên có thể truy cập vào hàm bên trong:

>>>

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!

Trong mã này, bạn xác định

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 bên trong
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7 để in thông báo
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8 lên màn hình. Để làm điều đó, bạn gọi
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 trên dòng cuối cùng của
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7. Đây là cách nhanh nhất để viết một chức năng bên trong trong Python. Tuy nhiên, các chức năng bên trong cung cấp rất nhiều khả năng thú vị ngoài những gì bạn thấy trong ví dụ này.nonlocal names. They are nonlocal from the
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 point of view.

Tính năng cốt lõi của các hàm bên trong là khả năng truy cập các biến và đối tượng từ chức năng kèm theo của chúng ngay cả sau khi chức năng này đã trở lại. Hàm kèm theo cung cấp một không gian tên có thể truy cập vào hàm bên trong:

>>>

>>> def factorial(number):
...     # Validate input
...     if not isinstance(number, int):
...         raise TypeError("Sorry. 'number' must be an integer.")
...     if number < 0:
...         raise ValueError("Sorry. 'number' must be zero or positive.")
...     # Calculate the factorial of number
...     def inner_factorial(number):
...         if number <= 1:
...             return 1
...         return number * inner_factorial(number - 1)
...     return inner_factorial(number)
...

>>> factorial(4)
24

Trong mã này, bạn xác định

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 bên trong
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7 để in thông báo
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8 lên màn hình. Để làm điều đó, bạn gọi
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 trên dòng cuối cùng của
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7. Đây là cách nhanh nhất để viết một chức năng bên trong trong Python. Tuy nhiên, các chức năng bên trong cung cấp rất nhiều khả năng thú vị ngoài những gì bạn thấy trong ví dụ này.

Tính năng cốt lõi của các hàm bên trong là khả năng truy cập các biến và đối tượng từ chức năng kèm theo của chúng ngay cả sau khi chức năng này đã trở lại. Hàm kèm theo cung cấp một không gian tên có thể truy cập vào hàm bên trong:

Bây giờ bạn có thể chuyển một chuỗi dưới dạng đối số cho >>> def outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 7 và >>> def outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 6 sẽ truy cập vào đối số đó thông qua tên >>> def factorial(number): ... # Validate input ... if not isinstance(number, int): ... raise TypeError("Sorry. 'number' must be an integer.") ... if number < 0: ... raise ValueError("Sorry. 'number' must be zero or positive.") ... # Calculate the factorial of number ... def inner_factorial(number): ... if number <= 1: ... return 1 ... return number * inner_factorial(number - 1) ... return inner_factorial(number) ... >>> factorial(4) 24 3. Tên này, tuy nhiên, được xác định trong phạm vi địa phương là >>> def outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 7. Các tên mà bạn xác định trong phạm vi cục bộ của một hàm bên ngoài được gọi là tên không thuộc địa. Chúng không thuộc về quan điểm >>> def outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 6.

Dưới đây, một ví dụ về cách tạo và sử dụng hàm bên trong phức tạp hơn:

Trong >>> def factorial(number): ... # Validate input ... if not isinstance(number, int): ... raise TypeError("Sorry. 'number' must be an integer.") ... if number < 0: ... raise ValueError("Sorry. 'number' must be zero or positive.") ... # Calculate the factorial of number ... def inner_factorial(number): ... if number <= 1: ... return 1 ... return number * inner_factorial(number - 1) ... return inner_factorial(number) ... >>> factorial(4) 24 6, trước tiên bạn xác nhận dữ liệu đầu vào để đảm bảo rằng người dùng của bạn đang cung cấp một số nguyên bằng hoặc lớn hơn 0. Sau đó, bạn xác định hàm bên trong đệ quy gọi là >>> def factorial(number): ... # Validate input ... if not isinstance(number, int): ... raise TypeError("Sorry. 'number' must be an integer.") ... if number < 0: ... raise ValueError("Sorry. 'number' must be zero or positive.") ... # Calculate the factorial of number ... def inner_factorial(number): ... if number <= 1: ... return 1 ... return number * inner_factorial(number - 1) ... return inner_factorial(number) ... >>> factorial(4) 24 7 thực hiện tính toán giai thừa và trả về kết quả. Bước cuối cùng là gọi >>> def factorial(number): ... # Validate input ... if not isinstance(number, int): ... raise TypeError("Sorry. 'number' must be an integer.") ... if number < 0: ... raise ValueError("Sorry. 'number' must be zero or positive.") ... # Calculate the factorial of number ... def inner_factorial(number): ... if number <= 1: ... return 1 ... return number * inner_factorial(number - 1) ... return inner_factorial(number) ... >>> factorial(4) 24 7.

Ưu điểm chính của việc sử dụng mẫu này là, bằng cách thực hiện tất cả các đối số kiểm tra trong hàm bên ngoài, bạn có thể bỏ qua kiểm tra lỗi một cách an toàn trong hàm bên trong và tập trung vào tính toán trong tay.encapsulation.

Sử dụng các chức năng bên trong: những điều cơ bản

>>>

>>> def increment(number):
...     def inner_increment():
...         return number + 1
...     return inner_increment()
...

>>> increment(10)
11

>>> # Call inner_increment()
>>> inner_increment()
Traceback (most recent call last):
  File "", line 1, in 
    inner_increment()
NameError: name 'inner_increment' is not defined

Trong mã này, bạn xác định

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 bên trong
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7 để in thông báo
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8 lên màn hình. Để làm điều đó, bạn gọi
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 trên dòng cuối cùng của
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7. Đây là cách nhanh nhất để viết một chức năng bên trong trong Python. Tuy nhiên, các chức năng bên trong cung cấp rất nhiều khả năng thú vị ngoài những gì bạn thấy trong ví dụ này.

Tính năng cốt lõi của các hàm bên trong là khả năng truy cập các biến và đối tượng từ chức năng kèm theo của chúng ngay cả sau khi chức năng này đã trở lại. Hàm kèm theo cung cấp một không gian tên có thể truy cập vào hàm bên trong:

Bây giờ bạn có thể chuyển một chuỗi dưới dạng đối số cho

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7 và
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6 sẽ truy cập vào đối số đó thông qua tên
>>> def factorial(number):
...     # Validate input
...     if not isinstance(number, int):
...         raise TypeError("Sorry. 'number' must be an integer.")
...     if number < 0:
...         raise ValueError("Sorry. 'number' must be zero or positive.")
...     # Calculate the factorial of number
...     def inner_factorial(number):
...         if number <= 1:
...             return 1
...         return number * inner_factorial(number - 1)
...     return inner_factorial(number)
...

>>> factorial(4)
24
3. Tên này, tuy nhiên, được xác định trong phạm vi địa phương là
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
7. Các tên mà bạn xác định trong phạm vi cục bộ của một hàm bên ngoài được gọi là tên không thuộc địa. Chúng không thuộc về quan điểm
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
6.

# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)

Dưới đây, một ví dụ về cách tạo và sử dụng hàm bên trong phức tạp hơn:

  1. Trong
    >>> def factorial(number):
    ...     # Validate input
    ...     if not isinstance(number, int):
    ...         raise TypeError("Sorry. 'number' must be an integer.")
    ...     if number < 0:
    ...         raise ValueError("Sorry. 'number' must be zero or positive.")
    ...     # Calculate the factorial of number
    ...     def inner_factorial(number):
    ...         if number <= 1:
    ...             return 1
    ...         return number * inner_factorial(number - 1)
    ...     return inner_factorial(number)
    ...
    
    >>> factorial(4)
    24
    
    6, trước tiên bạn xác nhận dữ liệu đầu vào để đảm bảo rằng người dùng của bạn đang cung cấp một số nguyên bằng hoặc lớn hơn 0. Sau đó, bạn xác định hàm bên trong đệ quy gọi là
    >>> def factorial(number):
    ...     # Validate input
    ...     if not isinstance(number, int):
    ...         raise TypeError("Sorry. 'number' must be an integer.")
    ...     if number < 0:
    ...         raise ValueError("Sorry. 'number' must be zero or positive.")
    ...     # Calculate the factorial of number
    ...     def inner_factorial(number):
    ...         if number <= 1:
    ...             return 1
    ...         return number * inner_factorial(number - 1)
    ...     return inner_factorial(number)
    ...
    
    >>> factorial(4)
    24
    
    7 thực hiện tính toán giai thừa và trả về kết quả. Bước cuối cùng là gọi
    >>> def factorial(number):
    ...     # Validate input
    ...     if not isinstance(number, int):
    ...         raise TypeError("Sorry. 'number' must be an integer.")
    ...     if number < 0:
    ...         raise ValueError("Sorry. 'number' must be zero or positive.")
    ...     # Calculate the factorial of number
    ...     def inner_factorial(number):
    ...         if number <= 1:
    ...             return 1
    ...         return number * inner_factorial(number - 1)
    ...     return inner_factorial(number)
    ...
    
    >>> factorial(4)
    24
    
    7.
  2. Ưu điểm chính của việc sử dụng mẫu này là, bằng cách thực hiện tất cả các đối số kiểm tra trong hàm bên ngoài, bạn có thể bỏ qua kiểm tra lỗi một cách an toàn trong hàm bên trong và tập trung vào tính toán trong tay.
  3. Sử dụng các chức năng bên trong: những điều cơ bản
  4. Các trường hợp sử dụng của các hàm bên trong Python rất khác nhau. Bạn có thể sử dụng chúng để cung cấp đóng gói và ẩn các chức năng của bạn khỏi quyền truy cập bên ngoài, bạn có thể viết các chức năng bên trong của người trợ giúp và bạn cũng có thể tạo các trình trang trí và trang trí. Trong phần này, bạn sẽ tìm hiểu về hai trường hợp sử dụng trước đây của các chức năng bên trong và trong các phần sau, bạn sẽ học cách tạo các chức năng và trang trí của nhà máy đóng cửa.

Cung cấp đóng gói

>>>

>>> from hotspots import process_hotspots

>>> file_obj = open("./NYC_Wi-Fi_Hotspot_Locations.csv", "r")
>>> process_hotspots(file_obj)
There are 3319 Wi-Fi hotspots in NYC.
LinkNYC - Citybridge has the most with 1868.

>>> process_hotspots("./NYC_Wi-Fi_Hotspot_Locations.csv")
There are 3319 Wi-Fi hotspots in NYC.
LinkNYC - Citybridge has the most with 1868.

Cho dù bạn gọi

>>> def increment(number):
...     def inner_increment():
...         return number + 1
...     return inner_increment()
...

>>> increment(10)
11

>>> # Call inner_increment()
>>> inner_increment()
Traceback (most recent call last):
  File "", line 1, in 
    inner_increment()
NameError: name 'inner_increment' is not defined
3 với đường dẫn tệp dựa trên chuỗi hoặc với đối tượng tệp, bạn sẽ nhận được kết quả tương tự.

Sử dụng các chức năng của người trợ giúp bên trong và bên trong

Thông thường, bạn tạo các chức năng bên trong trợ giúp như

>>> def increment(number):
...     def inner_increment():
...         return number + 1
...     return inner_increment()
...

>>> increment(10)
11

>>> # Call inner_increment()
>>> inner_increment()
Traceback (most recent call last):
  File "", line 1, in 
    inner_increment()
NameError: name 'inner_increment' is not defined
6 khi bạn muốn cung cấp đóng gói. Bạn cũng có thể tạo các chức năng bên trong nếu bạn nghĩ rằng bạn sẽ không gọi chúng ở bất cứ nơi nào khác ngoài chức năng chứa.

Mặc dù việc viết các chức năng trợ giúp của bạn là các chức năng bên trong đạt được kết quả mong muốn, nhưng bạn có thể được phục vụ tốt hơn bằng cách trích xuất chúng như các chức năng cấp cao nhất. Trong trường hợp này, bạn có thể sử dụng một dấu gạch dưới hàng đầu (

# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
1) dưới tên của hàm để chỉ ra rằng nó riêng tư với mô -đun hoặc lớp hiện tại. Điều này sẽ cho phép bạn truy cập các chức năng trợ giúp của bạn từ bất kỳ nơi nào khác trong mô -đun hoặc lớp hiện tại và sử dụng lại chúng khi cần thiết.

Trích xuất các chức năng bên trong vào các chức năng riêng tư cấp cao có thể làm cho mã của bạn sạch hơn và dễ đọc hơn. Thực tiễn này có thể tạo ra các chức năng áp dụng nguyên tắc tự chịu trách nhiệm đơn.

Giữ lại trạng thái với các chức năng bên trong: Đóng cửa

Trong Python, các chức năng là công dân hạng nhất. Điều này có nghĩa là họ ngang hàng với bất kỳ đối tượng nào khác, chẳng hạn như số, chuỗi, danh sách, bộ dữ liệu, mô -đun, v.v. Bạn có thể tự động tạo hoặc phá hủy chúng, lưu trữ chúng trong các cấu trúc dữ liệu, truyền chúng dưới dạng đối số cho các chức năng khác, sử dụng chúng làm giá trị trả về, v.v.

Bạn cũng có thể tạo các chức năng bậc cao trong Python. Các chức năng bậc cao là các hàm hoạt động trên các chức năng khác bằng cách coi chúng làm đối số, trả lại chúng hoặc cả hai.Higher-order functions are functions that operate on other functions by taking them as arguments, returning them, or both.

Tất cả các ví dụ về các chức năng bên trong mà bạn đã thấy cho đến nay là các chức năng thông thường xảy ra để được lồng trong các chức năng khác. Trừ khi bạn cần che giấu các chức năng của mình từ thế giới bên ngoài, thì không có lý do cụ thể nào để chúng được lồng. Bạn có thể định nghĩa các chức năng đó là các hàm cấp cao nhất và bạn sẽ rất tốt.

Trong phần này, bạn sẽ tìm hiểu về các chức năng của nhà máy đóng cửa. Đóng cửa là các chức năng được tạo động được trả về bởi các chức năng khác. Tính năng chính của họ là họ có quyền truy cập đầy đủ vào các biến và tên được xác định trong không gian tên cục bộ nơi đóng cửa được tạo, mặc dù hàm kèm theo đã trả về và thực hiện xong.closure factory functions. Closures are dynamically created functions that are returned by other functions. Their main feature is that they have full access to the variables and names defined in the local namespace where the closure was created, even though the enclosing function has returned and finished executing.

Trong Python, khi bạn trả về một đối tượng hàm bên trong, trình thông dịch sẽ đóng gói chức năng cùng với môi trường chứa hoặc đóng của nó. Đối tượng hàm giữ một ảnh chụp nhanh của tất cả các biến và tên được xác định trong phạm vi chứa của nó. Để xác định đóng cửa, bạn cần thực hiện ba bước:

  1. Tạo một hàm bên trong.
  2. Các biến tham chiếu từ hàm kèm theo.
  3. Trả về hàm bên trong.

Với kiến ​​thức cơ bản này, bạn có thể bắt đầu tạo sự đóng cửa của mình ngay lập tức và tận dụng tính năng chính của chúng: giữ trạng thái giữa các cuộc gọi chức năng.retaining state between function calls.

Giữ lại trạng thái đóng cửa

Việc đóng cửa làm cho chức năng bên trong giữ lại trạng thái của môi trường khi được gọi. Việc đóng cửa không phải là chức năng bên trong nhưng chức năng bên trong cùng với môi trường bao quanh của nó. Việc đóng nắm bắt các biến cục bộ và tên trong hàm chứa và giữ chúng xung quanh.

Xem xét ví dụ sau:

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power

Ở đây, những gì mà xảy ra trong chức năng này:

  • Dòng 3 tạo ra
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    2, là chức năng của nhà máy đóng cửa. Điều này có nghĩa là nó tạo ra một đóng cửa mới mỗi khi nó gọi và sau đó trả lại cho người gọi.
    creates
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    2, which is a closure factory function. This means that it creates a new closure each time it’s called and then returns it to the caller.
  • Dòng 4 xác định
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    3, là hàm bên trong có một đối số duy nhất,
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    4 và trả về kết quả của biểu thức
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    5.
    defines
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    3, which is an inner function that takes a single argument,
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    4, and returns the result of the expression
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    5.
  • Dòng 6 trả về
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    6 dưới dạng đối tượng hàm, mà không gọi nó.
    returns
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    6 as a function object, without calling it.

# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
3 nhận được giá trị của
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8 từ đâu? Đây là nơi đóng cửa đi vào chơi. Trong ví dụ này,
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
3 nhận được giá trị của
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8 từ hàm bên ngoài,
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
2. Ở đây, những gì Python làm khi bạn gọi
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
2:

  1. Xác định một thể hiện mới của
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    3, có một đối số duy nhất
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    4.
  2. Chụp ảnh chụp nhanh về trạng thái xung quanh
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    3, bao gồm
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    8 với giá trị hiện tại của nó.
  3. Trả lại
    # hotspots.py
    
    import csv
    from collections import Counter
    
    def process_hotspots(file):
        def most_common_provider(file_obj):
            hotspots = []
            with file_obj as csv_file:
                content = csv.DictReader(csv_file)
    
                for row in content:
                    hotspots.append(row["Provider"])
    
            counter = Counter(hotspots)
            print(
                f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
                f"{counter.most_common(1)[0][0]} has the most with "
                f"{counter.most_common(1)[0][1]}."
            )
    
        if isinstance(file, str):
            # Got a string-based filepath
            file_obj = open(file, "r")
            most_common_provider(file_obj)
        else:
            # Got a file object
            most_common_provider(file)
    
    3 cùng với toàn bộ trạng thái xung quanh.

Bằng cách này, khi bạn gọi phiên bản của

# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
3 được trả về bởi
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
2, bạn sẽ thấy rằng hàm này nhớ lại giá trị của
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8:

>>>

>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125

Trong các ví dụ này,

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
1 nhớ rằng
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
2 và
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
3 nhớ rằng
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
4. Lưu ý rằng cả hai đóng cửa đều nhớ
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8 tương ứng giữa các cuộc gọi.

Bây giờ hãy xem xét một ví dụ khác:

>>>

>>> def has_permission(page):
...     def permission(username):
...         if username.lower() == "admin":
...             return f"'{username}' has access to {page}."
...         else:
...             return f"'{username}' doesn't have access to {page}."
...     return permission
...

>>> check_admin_page_permision = has_permission("Admin Page")

>>> check_admin_page_permision("admin")
"'admin' has access to Admin Page."

>>> check_admin_page_permision("john")
"'john' doesn't have access to Admin Page."

Trong các ví dụ này,

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
1 nhớ rằng
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
2 và
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
3 nhớ rằng
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
4. Lưu ý rằng cả hai đóng cửa đều nhớ
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8 tương ứng giữa các cuộc gọi.

Thay vì kiểm tra xem người dùng có bằng

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
6 hay không, bạn có thể truy vấn cơ sở dữ liệu SQL để kiểm tra quyền và sau đó trả về chế độ xem chính xác tùy thuộc vào việc thông tin đăng nhập có chính xác hay không.

Bạn thường tạo ra các đóng cửa mà don không thể sửa đổi trạng thái bao quanh của chúng hoặc đóng cửa với trạng thái bao quanh tĩnh, như bạn đã thấy trong các ví dụ trên. Tuy nhiên, bạn cũng có thể tạo các đóng cửa sửa đổi trạng thái kèm theo của chúng bằng cách sử dụng các đối tượng có thể thay đổi, chẳng hạn như từ điển, bộ hoặc danh sách.static enclosing state, as you saw in the above examples. However, you can also create closures that modify their enclosing state by using mutable objects, such as dictionaries, sets, or lists.

Giả sử bạn cần tính giá trị trung bình của bộ dữ liệu. Dữ liệu đi kèm trong một luồng các phép đo liên tiếp của tham số được phân tích và bạn cần chức năng của mình để giữ lại các phép đo trước đó giữa các cuộc gọi. Trong trường hợp này, bạn có thể mã hóa chức năng đóng cửa của nhà máy như thế này:

>>>

>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0

Việc đóng cửa được gán cho

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7 giữ lại trạng thái của
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 giữa các cuộc gọi liên tiếp. Mặc dù bạn xác định
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 trong
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
0, nhưng nó vẫn có sẵn trong việc đóng cửa, vì vậy bạn có thể sửa đổi nó. Trong trường hợp này,
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 hoạt động như một loại trạng thái kèm theo động.

Sửa đổi trạng thái đóng cửa

Thông thường, các biến đóng được ẩn hoàn toàn khỏi thế giới bên ngoài. Tuy nhiên, bạn có thể cung cấp các hàm bên trong Getter và Setter cho chúng:getter and setter inner functions for them:

>>>

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
0

>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0

Việc đóng cửa được gán cho

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7 giữ lại trạng thái của
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 giữa các cuộc gọi liên tiếp. Mặc dù bạn xác định
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 trong
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
0, nhưng nó vẫn có sẵn trong việc đóng cửa, vì vậy bạn có thể sửa đổi nó. Trong trường hợp này,
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 hoạt động như một loại trạng thái kèm theo động.

Sửa đổi trạng thái đóng cửa

Thông thường, các biến đóng được ẩn hoàn toàn khỏi thế giới bên ngoài. Tuy nhiên, bạn có thể cung cấp các hàm bên trong Getter và Setter cho chúng:Decorators are higher-order functions that take a callable (function, method, class) as an argument and return another callable.

Ở đây,

>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
2 trả về một đóng cửa đại diện cho một đối tượng
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
3. Đối tượng này có các chức năng getter và setter đính kèm. Bạn có thể sử dụng các chức năng đó để có được quyền truy cập đọc và ghi vào các biến
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
4 và
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
5, được xác định trong phạm vi kèm theo và giao hàng với việc đóng cửa.

Mặc dù chức năng này tạo ra các đóng cửa có thể hoạt động nhanh hơn một lớp tương đương, bạn cần lưu ý rằng kỹ thuật này không cung cấp các tính năng chính, bao gồm kế thừa, thuộc tính, mô tả và phương pháp tĩnh và tĩnh. Nếu bạn muốn đi sâu hơn vào kỹ thuật này, thì hãy xem công cụ đơn giản để mô phỏng các lớp bằng cách sử dụng các phạm vi đóng và lồng nhau (công thức Python).

Thêm hành vi với các chức năng bên trong: Người trang trí

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
1

Trang trí Python là một trường hợp sử dụng phổ biến và thuận tiện cho các chức năng bên trong, đặc biệt là cho việc đóng cửa. Các nhà trang trí là các hàm bậc cao hơn có thể gọi (chức năng, phương pháp, lớp) làm đối số và trả lại một cuộc gọi khác.

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
2

Bạn có thể sử dụng các chức năng trang trí để thêm trách nhiệm vào một cuộc gọi hiện có một cách tự động và mở rộng hành vi của nó một cách minh bạch mà không ảnh hưởng hoặc sửa đổi bản gọi ban đầu có thể gọi được.

>>>

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
3

>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0

Việc đóng cửa được gán cho

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7 giữ lại trạng thái của
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 giữa các cuộc gọi liên tiếp. Mặc dù bạn xác định
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 trong
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
0, nhưng nó vẫn có sẵn trong việc đóng cửa, vì vậy bạn có thể sửa đổi nó. Trong trường hợp này,
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 hoạt động như một loại trạng thái kèm theo động.

  • Sửa đổi trạng thái đóng cửa
  • Thông thường, các biến đóng được ẩn hoàn toàn khỏi thế giới bên ngoài. Tuy nhiên, bạn có thể cung cấp các hàm bên trong Getter và Setter cho chúng:
  • Ở đây,
    >>> from powers import generate_power
    
    >>> raise_two = generate_power(2)
    >>> raise_three = generate_power(3)
    
    >>> raise_two(4)
    16
    >>> raise_two(5)
    25
    
    >>> raise_three(4)
    64
    >>> raise_three(5)
    125
    
    2 trả về một đóng cửa đại diện cho một đối tượng
    >>> from powers import generate_power
    
    >>> raise_two = generate_power(2)
    >>> raise_three = generate_power(3)
    
    >>> raise_two(4)
    16
    >>> raise_two(5)
    25
    
    >>> raise_three(4)
    64
    >>> raise_three(5)
    125
    
    3. Đối tượng này có các chức năng getter và setter đính kèm. Bạn có thể sử dụng các chức năng đó để có được quyền truy cập đọc và ghi vào các biến
    >>> from powers import generate_power
    
    >>> raise_two = generate_power(2)
    >>> raise_three = generate_power(3)
    
    >>> raise_two(4)
    16
    >>> raise_two(5)
    25
    
    >>> raise_three(4)
    64
    >>> raise_three(5)
    125
    
    4 và
    >>> from powers import generate_power
    
    >>> raise_two = generate_power(2)
    >>> raise_three = generate_power(3)
    
    >>> raise_two(4)
    16
    >>> raise_two(5)
    25
    
    >>> raise_three(4)
    64
    >>> raise_three(5)
    125
    
    5, được xác định trong phạm vi kèm theo và giao hàng với việc đóng cửa.
  • Mặc dù chức năng này tạo ra các đóng cửa có thể hoạt động nhanh hơn một lớp tương đương, bạn cần lưu ý rằng kỹ thuật này không cung cấp các tính năng chính, bao gồm kế thừa, thuộc tính, mô tả và phương pháp tĩnh và tĩnh. Nếu bạn muốn đi sâu hơn vào kỹ thuật này, thì hãy xem công cụ đơn giản để mô phỏng các lớp bằng cách sử dụng các phạm vi đóng và lồng nhau (công thức Python).

Thêm hành vi với các chức năng bên trong: Người trang trí

>>>

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
4

>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0

Việc đóng cửa được gán cho

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7 giữ lại trạng thái của
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 giữa các cuộc gọi liên tiếp. Mặc dù bạn xác định
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 trong
>>> from powers import generate_power

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)

>>> raise_two(4)
16
>>> raise_two(5)
25

>>> raise_three(4)
64
>>> raise_three(5)
125
0, nhưng nó vẫn có sẵn trong việc đóng cửa, vì vậy bạn có thể sửa đổi nó. Trong trường hợp này,
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8 hoạt động như một loại trạng thái kèm theo động.

>>>

>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
5

>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0

Ở đây, người trang trí cần phải có một lập luận (

# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8), vì vậy bạn cần phải có hai cấp độ chức năng bên trong lồng nhau. Cấp độ đầu tiên được thể hiện bởi
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
3, lấy chức năng được trang trí làm đối số. Cấp độ thứ hai được biểu thị bằng
>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0
3, gói đối số
# hotspots.py

import csv
from collections import Counter

def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)

            for row in content:
                hotspots.append(row["Provider"])

        counter = Counter(hotspots)
        print(
            f"There are {len(hotspots)} Wi-Fi hotspots in NYC.\n"
            f"{counter.most_common(1)[0][0]} has the most with "
            f"{counter.most_common(1)[0][1]}."
        )

    if isinstance(file, str):
        # Got a string-based filepath
        file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # Got a file object
        most_common_provider(file)
8 trong
>>> def mean():
...     sample = []
...     def inner_mean(number):
...         sample.append(number)
...         return sum(sample) / len(sample)
...     return inner_mean
...

>>> sample_mean = mean()
>>> sample_mean(100)
100.0
>>> sample_mean(105)
102.5
>>> sample_mean(101)
102.0
>>> sample_mean(98)
101.0
5, đưa ra phép tính cuối cùng của công suất và trả về kết quả.

Sự kết luận

Nếu bạn xác định một hàm bên trong một hàm khác, thì bạn sẽ tạo ra một hàm bên trong, còn được gọi là hàm lồng nhau. Trong Python, các hàm bên trong có quyền truy cập trực tiếp vào các biến và tên mà bạn xác định trong hàm kèm theo. Điều này cung cấp một cơ chế để bạn tạo ra các chức năng, đóng cửa và trang trí của người trợ giúp.inner function, also known as a nested function. In Python, inner functions have direct access to the variables and names that you define in the enclosing function. This provides a mechanism for you to create helper functions, closures, and decorators.

Trong hướng dẫn này, bạn đã học được cách:

  • Cung cấp đóng gói bằng các chức năng làm tổ trong các chức năng khácencapsulation by nesting functions in other functions
  • Viết các chức năng của người trợ giúp để tái sử dụng các đoạn mãhelper functions to reuse pieces of code
  • Thực hiện các chức năng của nhà máy đóng cửa mà trạng thái giữ lại giữa các cuộc gọiclosure factory functions that retaining state between calls
  • Xây dựng các chức năng trang trí để cung cấp các chức năng mớidecorator functions to provide new functionalities

Bây giờ bạn đã sẵn sàng để tận dụng nhiều cách sử dụng của các hàm bên trong trong mã của riêng bạn. Nếu bạn có bất kỳ câu hỏi hoặc nhận xét, thì hãy chắc chắn chia sẻ phần trong phần bình luận bên dưới.

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để làm sâu sắc thêm sự hiểu biết của bạn: các chức năng bên trong của Python This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Python Inner Functions

Làm thế nào để bạn gọi một hàm bên trong một hàm?

Python có hỗ trợ các chức năng lồng nhau không?define the inner function inside the outer function and invoke it. When using the function keyword, the function gets hoisted to the top of the scope and can be called from anywhere inside of the outer function.

Vì vậy, trong Python, các hàm lồng nhau có quyền truy cập trực tiếp vào các biến và tên mà bạn xác định trong hàm kèm theo. Nó cung cấp một cơ chế để đóng gói các chức năng, tạo ra các giải pháp trợ giúp và thực hiện các công cụ đóng cửa và trang trí.

Để gọi một hàm bên trong một hàm khác, hãy xác định hàm bên trong hàm bên ngoài và gọi nó. Khi sử dụng từ khóa chức năng, hàm được nâng lên trên cùng của phạm vi và có thể được gọi từ bất cứ nơi nào bên trong hàm bên ngoài.

Làm thế nào để bạn gọi một chức năng phụ trong Python?

Chức năng gọi trong Python..
hàm def function_name ():.
Statement1..
function_name () # gọi trực tiếp chức năng ..
# Chức năng gọi bằng cách sử dụng chức năng tích hợp ..
hàm def function_name ():.
function_name () # gọi trực tiếp chức năng ..
# Chức năng gọi bằng cách sử dụng chức năng tích hợp ..

str = function_name ('john') # gán chức năng để gọi hàm ..

in (str) # in câu lệnh ..