Hướng dẫn inner function python - hàm bên trong python

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

Nội phân chính

  • Tạo các chức năng bên trong Python
  • Sử dụng các chức năng bên trong: những điều cơ bản
  • Cung cấp đóng gói
  • Xây dựng các chức năng bên trong của người trợ giúp
  • Sử dụng các chức năng của người trợ giúp bên trong và bên trong
  • Giữ lại trạng thái với các chức năng bên trong: Đóng cửa
  • Giữ lại trạng thái đóng cửa
  • Sửa đổi trạng thái đóng cửa
  • Thêm hành vi với các chức năng bên trong: Người trang trí
  • Làm thế nào để bạn truy cập một chức năng trong một chức năng Python?
  • Làm thế nào để bạn truy cập các chức năng lồng nhau trong Python?
  • Làm thế nào để bạn truy cập một chức năng bên trong một lớp trong Python?
  • Chức năng bên trong Python có thể truy cập biến bên ngoài không?

Nội phân chính

  • Tạo các chức năng bên trong Python
  • Sử dụng các chức năng bên trong: những điều cơ bản
  • Cung cấp đóng gói
  • Xây dựng các chức năng bên trong của người trợ giúp
  • Sử dụng các chức năng của người trợ giúp bên trong và bên trong
  • Giữ lại trạng thái với các chức năng bên trong: Đóng cửa
  • Giữ lại trạng thái đóng cửa
  • Sửa đổi trạng thái đóng cửa
  • Thêm hành vi với các chức năng bên trong: Người trang trí
  • Làm thế nào để bạn truy cập một chức năng trong một chức năng Python?
  • Làm thế nào để bạn truy cập các chức năng lồng nhau trong Python?
  • Làm thế nào để bạn truy cập một chức năng bên trong một lớp trong Python?
  • Chức năng bên trong Python có thể truy cập biến bên ngoài không?

Nội phân chính

  • Tạo các chức năng bên trong Python
  • Sử dụng các chức năng bên trong: những điều cơ bản
  • Cung cấp đóng gói
  • Xây dựng các chức năng bên trong của người trợ giúp
  • Sử dụng các chức năng của người trợ giúp bên trong và bên trong
  • Giữ lại trạng thái với các chức năng bên trong: Đóng cửa
  • Giữ lại trạng thái đóng cửa
  • Sửa đổi trạng thái đóng cửa
  • Thêm hành vi với các chức năng bên trong: Người trang trí
  • Làm thế nào để bạn truy cập một chức năng trong một chức năng Python?
  • Làm thế nào để bạn truy cập các chức năng lồng nhau trong Python?
  • Làm thế nào để bạn truy cập một chức năng bên trong một lớp trong Python?
  • Chức năng bên trong Python có thể truy cập biến bên ngoài không?

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:

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

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.

Cung cấp đóng gói

Một trường hợp sử dụng phổ biến của các hàm bên trong phát sinh khi bạn cần bảo vệ hoặc ẩn, một chức năng nhất định khỏi mọi thứ xảy ra bên ngoài để chức năng được ẩn hoàn toàn khỏi phạm vi toàn cầu. Loại hành vi này thường được gọi là đóng gói.encapsulation.

Ở đây, một ví dụ làm nổi bật khái niệm đó:

>>>

>>> 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 ví dụ này, bạn có thể truy cập trực tiếp vào

>>> 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
9. Nếu bạn cố gắng làm điều đó, thì bạn sẽ nhận được một
>>> 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
0. Điều đó vì
>>> 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
1 hoàn toàn ẩ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
9, ngăn bạn truy cập nó khỏi phạm vi toàn cầu.

Xây dựng các chức năng bên trong của người trợ giúp

Đôi khi bạn có một chức năng thực hiện cùng một đoạn mã ở một số nơi trong cơ thể của nó. Ví dụ: giả sử bạn muốn viết một chức năng để xử lý tệp CSV chứa thông tin về các điểm nóng Wi-Fi ở thành phố New York. Để tìm tổng số điểm nóng ở New York cũng như công ty cung cấp hầu hết trong số họ, bạn tạo ra tập lệnh sau:

# 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)

Ở đây,

>>> 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 lấy
>>> 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
4 làm đối số. Hàm kiểm tra xem
>>> 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
4 là đường dẫn dựa trên chuỗi đến tệp vật lý hoặc đối tượng tệp. Sau đó, nó gọi hàm bên trong trợ giúp
>>> 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, lấy một đối tượng tệp và thực hiện các hoạt động sau:

  1. Đọc nội dung tệp vào một trình tạo mang lại từ điển bằng cách sử dụng
    >>> 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
    
    7.
  2. Tạo một danh sách các nhà cung cấp Wi-Fi.
  3. Đếm số lượng điểm nóng Wi-Fi trên mỗi nhà cung cấp bằng đối tượng
    >>> 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
    
    8.
  4. In một tin nhắn với thông tin được truy xuất.

Nếu bạn chạy chức năng, thì bạn sẽ nhận được đầu ra sau:

>>>

>>> 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.

Trong ví dụ này, bạn có thể truy cập trực tiếp vào

>>> 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
9. Nếu bạn cố gắng làm điều đó, thì bạn sẽ nhận được một
>>> 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
0. Điều đó vì
>>> 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
1 hoàn toàn ẩ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
9, ngăn bạn truy cập nó khỏi phạm vi toàn cầu.

Xây dựng các chức năng bên trong của người trợ giúp

Đôi khi bạn có một chức năng thực hiện cùng một đoạn mã ở một số nơi trong cơ thể của nó. Ví dụ: giả sử bạn muốn viết một chức năng để xử lý tệp CSV chứa thông tin về các điểm nóng Wi-Fi ở thành phố New York. Để tìm tổng số điểm nóng ở New York cũng như công ty cung cấp hầu hết trong số họ, bạn tạo ra tập lệnh sau:

Ở đây,

>>> 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 lấy
>>> 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
4 làm đối số. Hàm kiểm tra xem
>>> 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
4 là đường dẫn dựa trên chuỗi đến tệp vật lý hoặc đối tượng tệp. Sau đó, nó gọi hàm bên trong trợ giúp
>>> 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, lấy một đối tượng tệp và thực hiện các hoạt động sau:

Đọc nội dung tệp vào một trình tạo mang lại từ điển bằng cách sử dụng

>>> 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
7.

Tạo một danh sách các nhà cung cấp Wi-Fi.

Đếm số lượng điểm nóng Wi-Fi trên mỗi nhà cung cấp bằng đối tượng

>>> 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
8.

In một tin nhắn với thông tin được truy xuất.Higher-order functions are functions that operate on other functions by taking them as arguments, returning them, or both.

Nếu bạn chạy chức năng, thì bạn sẽ nhận được đầu ra sau:

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ự.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.

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

  1. 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.
  2. 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.
  3. 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ửaretaining state between function calls.

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.

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.

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

Hàm bên trong kiểm tra xem một người dùng nhất định có quyền truy cập chính xác để truy cập một trang nhất định. Bạn có thể nhanh chóng sửa đổi điều này để lấy người dùng trong phiên để kiểm tra xem họ có thông tin đăng nhập chính xác để truy cập một tuyến đường nhất định không.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.

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.

>>>

>>> 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

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:

Hàm bên trong kiểm tra xem một người dùng nhất định có quyền truy cập chính xác để truy cập một trang nhất định. Bạn có thể nhanh chóng sửa đổi điều này để lấy người dùng trong phiên để kiểm tra xem họ có thông tin đăng nhập chính xác để truy cập một tuyến đường nhất định khô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

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:

Hàm bên trong kiểm tra xem một người dùng nhất định có quyền truy cập chính xác để truy cập một trang nhất định. Bạn có thể nhanh chóng sửa đổi điều này để lấy người dùng trong phiên để kiểm tra xem họ có thông tin đăng nhập chính xác để truy cập một tuyến đường nhất định không.

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.Decorators are higher-order functions that take a callable (function, method, class) as an argument and return another callable.

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.

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:

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!
1

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

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

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

Dưới đây, một ví dụ về cách xây dựng chức năng trang trí để thêm chức năng mới vào một chức năng hiện có:

>>>

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

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

Trong trường hợp này, bạn sử dụ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
9 để trang trí
>>> 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."
0. Điều này thêm chức năng mới cho chức năng được trang trí. Bây giờ khi bạn gọi
>>> 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."
0, thay vì chỉ in
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8, chức năng của bạn in hai tin nhắn mới.

Các trường hợp sử dụng cho trang trí Python rất đa dạng. Dưới đây là một số trong số họ:

  • Gỡ lỗi
  • Bộ nhớ đệm
  • Đăng nhập
  • Thời gian

Một thông lệ phổ biến để gỡ lỗi mã Python là chèn các cuộc gọi vào

>>> 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."
3 để kiểm tra các giá trị của các biến, để xác nhận rằng một khối mã được thực thi, v.v. Thêm và xóa các cuộc gọi vào
>>> 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."
3 có thể gây khó chịu và bạn có nguy cơ quên một số trong số chúng. Để ngăn chặn tình huống này, bạn có thể viết một người trang trí như thế này:

>>>

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

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

Trong trường hợp này, bạn sử dụ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
9 để trang trí
>>> 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."
0. Điều này thêm chức năng mới cho chức năng được trang trí. Bây giờ khi bạn gọi
>>> 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."
0, thay vì chỉ in
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
8, chức năng của bạn in hai tin nhắn mới.

Các trường hợp sử dụng cho trang trí Python rất đa dạng. Dưới đây là một số trong số họ:

>>>

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

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

Gỡ lỗi

Bộ nhớ đệm

Đăng nhập

Thời gianinner 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.

Một thông lệ phổ biến để gỡ lỗi mã Python là chèn các cuộc gọi vào

>>> 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."
3 để kiểm tra các giá trị của các biến, để xác nhận rằng một khối mã được thực thi, v.v. Thêm và xóa các cuộc gọi vào
>>> 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."
3 có thể gây khó chịu và bạn có nguy cơ quên một số trong số chúng. Để ngăn chặn tình huống này, bạn có thể viết một người trang trí như thế này:

  • Ví dụ này cung cấp
    >>> 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."
    
    5, là một nhà trang trí có chức năng như một đối số và in chữ ký của nó với giá trị hiện tại của mỗi đối số và giá trị trả về tương ứng của nó. Bạn có thể sử dụng bộ trang trí này để gỡ lỗi các chức năng của bạn. Khi bạn nhận được kết quả mong muốn, bạn có thể loại bỏ người trang trí gọi
    >>> 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."
    
    6 và chức năng của bạn sẽ sẵn sàng cho bước tiếp theo.encapsulation by nesting functions in other functions
  • Ở đây, một ví dụ cuối cùng về cách tạo ra một người trang trí. Lần này, bạn sẽ tái tạo 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)
    
    2 như một hàm trang trí:helper functions to reuse pieces of code
  • Phiên bả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)
    
    2 này tạo ra kết quả tương tự mà bạn có trong triển khai ban đầu. Trong trường hợp này, bạn sử dụng cả đóng cửa để ghi 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 và một trình trang trí trả về phiên bản sửa đổi của hàm đầu vào,
    >>> 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
    
    0.closure factory functions that retaining state between calls
  • Ở đâ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ả.decorator functions to provide new functionalities

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. 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

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áccalling make_adder() would have been simpler. Incidentally, as you can see, functions are first-class objects in Python. make_adder is an object, and by adding (somearguments) you invoke, or call the function. In this case, that function returns another function object, one that you can call as well.

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ã

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ọideclare them explicitly as non-local (using nonlocal keyword) in order to modify them. Following is an example of a nested function accessing a non-local variable.

Xây dựng các chức năng trang trí để cung cấp các chức năng mới

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.instantiate a class into an object. Then we can access the method as an instance method of the class as shown in the program below. Here through the self parameter, instance methods can access attributes and other methods on the same object.

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

Làm thế nào để bạn truy cập một chức năng trong một chức năng Python? as well as the global variables. The inner functions variable has a local scope that is limited only to that function. Inner Functions variables can't be accessed at the outer function scope.