Hướng dẫn python call function from nested class - hàm gọi python từ lớp lồng nhau

Bạn đã biến phương thức thành một hàm tĩnh; Điều này loại bỏ tất cả bối cảnh khỏi một hàm (nó vẫn không bị ràng buộc).

Show

Thay vào đó, bạn có thể biến phương thức thành

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
8, vì vậy nó bị ràng buộc với lớp:

class KN():
    @staticmethod
    def create_model():
        return "This is KN Model"

    @classmethod
    def classifier(cls):
        arg = cls.create_model()

Tôi đã biến

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
9 một hàm tĩnh ở đó và để nó trả về giá trị chuỗi thay vì sử dụng
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

Hoặc, vì bạn đang tạo các trường hợp, bạn cũng có thể thực hiện các phương pháp thường xuyên sau:

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()

Tuy nhiên, tôi lo ngại rằng bạn đang tiếp cận Python đến từ Java hoặc C# ở đây. Nếu vậy, thì hãy biết rằng thuật ngữ

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

>>> outer_func()
Hello, World!
1 có một ý nghĩa khác trong Python; Bạn không xác định dữ liệu và phương thức trên mỗi lớp ở đây. Bạn thường sử dụng các thuộc tính lớp và phương thức lớp trong đó trong các ngôn ngữ khác mà bạn sẽ tạo ra mọi thứ
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

Python cũng không có mô hình quyền riêng tư, điều này đòi hỏi các lớp lồng nhau phải có thể chia sẻ quyền truy cập vào các hoạt động bên trong của lớp cha. Nếu bạn muốn tạo một không gian tên lồng nhau, trong Python, bạn thường sẽ sử dụng các mô -đun thay thế, tại thời điểm đó

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

>>> outer_func()
Hello, World!
3 sẽ là một gói và
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

>>> outer_func()
Hello, World!
5 mỗi mô -đun có chứa các chức năng đơn giản (vì vậy
class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
9 sẽ là một toàn cầu khác mà
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!
7 sẽ gọi).

Xây dựng các chức năng trang trí để cung cấp các chức năng mới 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

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

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 gọi một hàm bên trong một lớp trong Python?encapsulation and hide your functions from external access
  • Để gọi hàm tĩnh được xác định trước, chỉ cần nhập tên lớp theo sau là dấu chấm và tên hàm. Để gọi chức năng Java không tĩnh do người dùng hoặc được xác định trước, hãy tạo một đối tượng lớp và sau đó làm theo dấu chấm. Cú pháp để gọi hàm.helper functions to facilitate code reuse
  • Làm thế nào để bạn gọi một hàm bên trong một chức năng khác trong Python?closure factory functions that retain state between calls
  • Trong Python, có thể chuyển một chức năng như một đối số cho một hàm khác. Viết một hàm sử dụng (func, num) có hàm và một số làm đối số. Việc sử dụng sẽ tạo ra đầu ra được hiển thị trong các ví dụ được đưa ra dưới đây.decorator functions to add behavior to existing functions

Làm thế nào để bạn gọi một hàm bên trong từ hàm bên ngoài 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():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!
8 bên trong
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

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

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

>>> outer_func()
Hello, World!
9. Đâ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():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!
8 bên trong
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

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

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

>>> outer_func()
Hello, World!
9. Đâ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():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!
8 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():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

>>> outer_func()
Hello, World!
8 bên trong
>>> def outer_func():
...     def inner_func():
...         print("Hello, World!")
...     inner_func()
...

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

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

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

>>> outer_func()
Hello, World!
9. Đâ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(): ... def inner_func(): ... print("Hello, World!") ... inner_func() ... >>> outer_func() Hello, World! 9 và >>> def outer_func(): ... def inner_func(): ... print("Hello, World!") ... inner_func() ... >>> outer_func() Hello, World! 8 sẽ truy cập vào đối số đó thông qua tên >>> def outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 5. Tên này, tuy nhiên, được xác định trong phạm vi địa phương là >>> def outer_func(): ... def inner_func(): ... print("Hello, World!") ... inner_func() ... >>> outer_func() Hello, World! 9. 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(): ... def inner_func(): ... print("Hello, World!") ... inner_func() ... >>> outer_func() Hello, World! 8.

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 outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 8, 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 outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 9 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 outer_func(who): ... def inner_func(): ... print(f"Hello, {who}") ... inner_func() ... >>> outer_func("World!") Hello, World! 9.

Ư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

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

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.

# 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, một ví dụ làm nổi bật khái niệm đó:

  1. 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
    
    1. Nếu bạn cố gắng làm điều đó, thì bạn sẽ nhận được
    >>> 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
    
    2. Điều đó bởi vì
    >>> 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 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
    
    1, ngăn bạn truy cập nó khỏi phạm vi toàn cầu.
  2. Xây dựng các chức năng bên trong của người trợ giúp
  3. Đô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:
  4. Ở đây,
    >>> 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
    
    5 lấy
    >>> 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 làm đối số. Hàm kiểm tra xem
    >>> 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 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 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
    
    8, 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 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.

>>>

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

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

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:

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
    >>> 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à 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
    >>> 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, 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
    >>> 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
    
    5, là hàm bên trong có một đối số duy nhấ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
    
    6 và trả về kết quả của biểu thức
    >>> 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.
    defines
    >>> 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
    
    5, which is an inner function that takes a single argument,
    >>> 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, and returns the result of the expression
    >>> 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.
  • Dòng 6 trả 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
    
    8 dưới dạng đối tượng hàm, mà không gọi nó.
    returns
    >>> 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 as a function object, without calling it.

>>> 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
5 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)
0 từ đâu? Đây là nơi đóng cửa đi vào chơi. Trong ví dụ nà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
5 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)
0 từ hàm bên ngoà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
4. Ở đây, những gì Python làm khi 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
4:

  1. Xác định một thể hiện mới của
    >>> 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
    
    5, có một đối số duy nhấ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
    
    6.
  2. Chụp ảnh chụp nhanh về trạng thái xung quanh
    >>> 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
    
    5, 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)
    
    0 với giá trị hiện tại của nó.
  3. Trả lạ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
    
    5 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

>>> 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
5 được trả về bở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
4, 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)
0:

>>>

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

>>> 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.
3 nhớ rằng
>>> 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.
4 và
>>> 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.
5 nhớ rằng
>>> 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.
6. 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)
0 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:

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
0

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

>>> 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.
3 nhớ rằng
>>> 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.
4 và
>>> 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.
5 nhớ rằng
>>> 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.
6. 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)
0 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

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

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
1

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

>>> 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.
9 giữ lại trạng thái
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
0 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
0 trong
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
2, 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
0 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:

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
2

Ở đây,

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
4 trả về một đóng cửa đại diện cho một đối tượng
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
5. Đố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
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
6 và
 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7, đượ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í

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

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.

Để tạo một trình trang trí, bạn chỉ cần xác định một người có thể gọi (một hàm, phương thức hoặc lớp) chấp nhận một đối tượng hàm là đối số, xử lý nó và trả về một đối tượng chức năng khác với hành vi được thêm vào.

Khi bạn có chức năng trang trí của mình tại chỗ, bạn có thể áp dụng nó cho bất kỳ cuộc gọi nào có thể gọi được. Để làm như vậy, bạn cần sử dụng biểu tượng AT (

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
8) trước tên của người trang trí và sau đó đặt nó lên dòng riêng của nó ngay trước khi có thể gọi được trang trí:

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
3

Cú pháp này làm cho

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
9 tự động lấ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
0 làm đối số và xử lý nó trong cơ thể của nó. Hoạt động này là một tốc ký cho bài tập sau:

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
4

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

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
5

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
1 để trang trí
>>> 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. Đ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
>>> 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, thay vì chỉ in
>>> def outer_func(who):
...     def inner_func():
...         print(f"Hello, {who}")
...     inner_func()
...

>>> outer_func("World!")
Hello, World!
0, 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

>>> 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 để 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
>>> 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ó 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:

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
6

Ví dụ này cung cấp

>>> 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
7, 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
>>> 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
8 và chức năng của bạn sẽ sẵn sàng cho bước tiếp theo.

Ở đâ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

>>> 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 như một hàm trang trí:

>>>

class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
7

Phiên 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
4 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)
0 và một trình trang trí trả về phiên bản sửa đổi của hàm đầu vào,
class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
02.

Ở đâ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)
0), 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 đại diện bở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
5, lấy chức năng được trang trí làm đối số. Cấp độ thứ hai được biểu thị bằng
class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
05, 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)
0 trong
class KN():
    def create_model(self):
        return "This is KN Model"

    def classifier(self):
        arg = self.create_model()
07, đư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 lớp trong Python?

Để gọi hàm tĩnh được xác định trước, chỉ cần nhập tên lớp theo sau là dấu chấm và tên hàm. Để gọi chức năng Java không tĩnh do người dùng hoặc được xác định trước, hãy tạo một đối tượng lớp và sau đó làm theo dấu chấm. Cú pháp để gọi hàm.type the class name followed by a dot and a function name. To call a user-defined or predefined non-static java function, create a class object and then follow the dot “.” syntax to call the function.

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

Trong Python, có thể chuyển một chức năng như một đối số cho một hàm khác.Viết một hàm sử dụng (func, num) có hàm và một số làm đối số.Việc sử dụng sẽ tạo ra đầu ra được hiển thị trong các ví dụ được đưa ra dưới đây.Write a function useFunction(func, num) that takes in a function and a number as arguments. The useFunction should produce the output shown in the examples given below.

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

Để tạo một bộ trang trí, hãy xác định một hàm và chuyển nó đến một hàm bên ngoài như một đối số.Hàm được truyền này sau đó được gọi trong một hàm bên trong khác, nơi bạn có thể sử dụng nó và thực hiện logic.Cuối cùng, hàm bên ngoài trả về hàm bên trong có chứa hành vi được sửa đổi.define a function and pass it to an outer function as an argument. This passed function is then called within another inner function where you can use it and implement logic. Finally the outer function returns the inner function which contains the modified behavior.

Các lớp lồng nhau có phải là Pythonic không?

Một lớp được xác định trong một lớp khác được gọi là lớp bên trong hoặc lớp lồng nhau.Nếu một đối tượng được tạo bằng cách sử dụng lớp bên trong lớp con thì đối tượng cũng có thể được sử dụng bởi lớp cha hoặc lớp gốc.. If an object is created using child class means inner class then the object can also be used by parent class or root class.