Xác định chức năng bên trong lớp javascript

Các hàm 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 hàm khác. Trong Python, loại hàm 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 hàm bên trong có nhiều công dụng, đáng chú ý nhất là các hàm đóng và hàm trang trí

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

  • Cung cấp khả năng đóng gói và ẩn các chức năng của bạn khỏi sự truy cập từ bên ngoài
  • Viết các hàm trợ giúp để tạo điều kiện sử dụng lại mã
  • Tạo các chức năng nhà máy đóng cửa giữ nguyên trạng thái giữa các cuộc gọi
  • Các chức năng trang trí mã để thêm hành vi vào các chức năng hiện có

Tiền thưởng miễn phí. Nhấp vào đây để nhận Bảng cheat Python và tìm hiểu kiến ​​thức cơ bản về Python 3, như làm việc với các kiểu dữ liệu, từ điển, danh sách và hàm Python

Tạo các hàm 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 trong chức năng kèm theo. Đây là một ví dụ về cách tạo một hàm bên trong trong 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 ra 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 ở 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 hàm bên 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ừ hàm kèm theo của chúng ngay cả sau khi hàm này đã trả về. Hàm kèm theo cung cấp một không gian tên mà hàm bên trong có thể truy cập được

>>>

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

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

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 đố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. Tuy nhiên, tên này được định nghĩa trong
>>> 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 hàm bên ngoài được gọi là tên không cục bộ. Họ không phải là người địa phương theo quan điểm
>>> def outer_func(who):
..     def inner_func():
..         print(f"Hello, {who}")
..     inner_func()
...

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

Đây là một ví dụ về cách tạo và sử dụng một hàm bên trong phức tạp hơ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

Trong

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

>>> factorial(4)
24
6, trước tiên bạn xác thực 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 một hàm bên trong đệ quy có tên là
>>> def factorial(number):
..     # Validate input
..     if not isinstance(number, int):
..         raise TypeError("Sorry. 'number' must be an integer.")
..     if number < 0:
..         raise ValueError("Sorry. 'number' must be zero or positive.")
..     # Calculate the factorial of number
..     def inner_factorial(number):
..         if number <= 1:
..             return 1
..         return number * inner_factorial(number - 1)
..     return inner_factorial(number)
...

>>> factorial(4)
24
7 thực hiện phép tính giai thừa và trả về kết quả. Bước cuối cùng là gọi
>>> def factorial(number):
..     # Validate input
..     if not isinstance(number, int):
..         raise TypeError("Sorry. 'number' must be an integer.")
..     if number < 0:
..         raise ValueError("Sorry. 'number' must be zero or positive.")
..     # Calculate the factorial of number
..     def inner_factorial(number):
..         if number <= 1:
..             return 1
..         return number * inner_factorial(number - 1)
..     return inner_factorial(number)
...

>>> factorial(4)
24
7

Ghi chú. Để thảo luận chi tiết hơn về đệ quy và các hàm đệ quy, hãy xem Tư duy đệ quy trong Python và Đệ quy trong Python. Một lời giới thiệu

Ư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ả việc kiểm tra đối số trong hàm bên ngoài, bạn có thể bỏ qua việc kiểm tra lỗi trong hàm bên trong một cách an toàn và tập trung vào việc tính toán trong tầm tay

Loại bỏ các quảng cáo

Sử dụng các chức năng bên trong. Những thứ cơ bản

Các trường hợp sử dụng hàm bên trong Python rất đa dạng. Bạn có thể sử dụng chúng để cung cấp khả năng đóng gói và ẩn các hàm của mình khỏi sự truy cập từ bên ngoài, bạn có thể viết các hàm bên trong của trình trợ giúp và bạn cũng có thể tạo các bao đóng 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 của các hàm bên trong và trong các phần sau, bạn sẽ tìm hiểu cách tạo và

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 hàm nhất định khỏi mọi thứ xảy ra bên ngoài nó để hàm đó hoàn toàn bị ẩ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

Đây là 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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined

Trong ví dụ này, bạn không 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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
0. Đó là bởi 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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
1 ẩn hoàn toà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ó từ phạm vi toàn cầu

Xây dựng chức năng bên trong Helper

Đôi khi, bạn có một hàm thực hiện cùng một đoạn mã ở một số vị trí trong nội dung của nó. Ví dụ: giả sử bạn muốn viết một hàm để xử lý tệp CSV chứa thông tin về các điểm truy cập Wi-Fi ở Thành phố New York. Để tìm tổng số điểm phát sóng ở New York cũng như công ty cung cấp hầu hết các điểm phát sóng này, bạn tạo 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 "<input>", line 1, in <module>
    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 "<input>", line 1, in <module>
    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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
4 có phải là đường dẫn dựa trên chuỗi tới tệp vật lý hoặc tệp. Sau đó, nó gọi hàm bên trong của trình 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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
6, hàm này nhận một đối tượng tệp và thực hiện các thao tác sau

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

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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
3 bằng đường dẫn tệp dựa trên chuỗi hay bằng đối tượng tệp, bạn đều nhận được kết quả như nhau

Sử dụng các chức năng trợ giúp bên trong và riêng tư

Thông thường, bạn tạo các hàm bên trong của trình 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 "<input>", line 1, in <module>
    inner_increment()
NameError: name 'inner_increment' is not defined
6 khi bạn muốn cung cấp khả năng đóng gói. Bạn cũng có thể tạo các hàm bên trong nếu bạn nghĩ rằng mình sẽ không gọi chúng ở bất kỳ nơi nào khác ngoài hàm chứa

Mặc dù việc viết các hàm trợ giúp của bạn dưới dạng các hàm bên trong đạt được kết quả mong muốn, nhưng có lẽ bạn sẽ được phục vụ tốt hơn bằng cách trích xuất chúng dưới dạng các hàm cấp cao nhất. Trong trường hợp này, bạn có thể sử dụng dấu gạch dưới ở đầ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) trong tên của hàm để cho biết rằng nó là riêng tư đối 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 của trình trợ giúp 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

Trích xuất các chức năng bên trong thành các chức năng riêng cấp cao nhất 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 do đó áp dụng nguyên tắc chịu trách nhiệm duy nhất

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à. Điều này có nghĩa là chúng ngang bằ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 hủy chúng, lưu trữ chúng trong cấu trúc dữ liệu, chuyển chúng làm đối số cho các hàm 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 hàm bậc cao hơn trong Python. Các hàm bậc cao hơn là các hàm hoạt động trên các hàm khác bằng cách lấy chúng làm đối số, trả về chúng hoặc cả hai

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

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. Bao đóng là các hàm được tạo động được trả về bởi các hàm khác. Tính năng chính của chúng là chúng có toàn quyền truy cập 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 tạo, mặc dù hàm kèm theo đã trả về và thực thi xong

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 hàm cùng với môi trường chứa hoặc bao đó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 thời điểm đóng cửa, bạn cần thực hiện ba bước

  1. Tạo một chức năng 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 các bao đóng 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ữ lại trạng thái giữa các lần gọi hàm

Loại bỏ các quảng cáo

Giữ lại trạng thái trong một kết thúc

Một bao đóng làm cho hàm bên trong giữ nguyên 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 mà là chức năng bên trong cùng với môi trường kèm theo của nó. Bao đó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 là những gì đang 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, đây là hàm đóng của nhà máy. Điều này có nghĩa là nó tạo một bao đóng mới mỗi khi nó được gọi và sau đó trả lại cho người gọi
  • Dòng 4 định nghĩ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, là một hàm bên trong nhận 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
  • 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ó

# 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 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? . 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 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 là 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, nhận một đối số duy nhất là
    # 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 nhanh trạng thái xung quanh 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, 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. Quay 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 của nó

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 ghi nhớ 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 những 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 lần đóng đề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 của chú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."

Hàm bên trong kiểm tra xem một người dùng nhất định có quyền chính xác để truy cập một trang nhất định hay không. 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 vào một tuyến đường nhất định hay 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ả lại chế độ xem chính xác tùy thuộc vào thông tin đăng nhập có chính xác hay không

Thông thường, bạn sẽ tạo các bao đóng không sửa đổi trạng thái bao quanh của chúng hoặc các bao đóng có 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 bao đóng để sửa đổi trạng thái bao quanh 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 một tập dữ liệu. Dữ liệu đến 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 lần gọi. Trong trường hợp này, bạn có thể mã hóa chức năng đóng của nhà máy như thế này

>>>_______ 58 _______

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

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

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

 1# powers.py
 2
 3def generate_power(exponent):
 4    def power(base):
 5        return base ** exponent
 6    return power
7 giữ nguyên 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 lần 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, nó vẫn có sẵn trong phần đóng, 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 bao quanh động

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

Thông thường, các biến đóng hoàn toàn bị ẩ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

>>>

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

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

Ở đây,

>>> from powers import generate_power

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

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

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

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

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

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

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

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

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

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

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

>>> raise_three(4)
64
>>> raise_three(5)
125
5, được xác định trong phạm vi kèm theo và vận chuyển cùng với bao đóng

Mặc dù hàm này tạo các bao đóng có thể hoạt động nhanh hơn một lớp tương đương, như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 tính kế thừa, thuộc tính, bộ mô tả, lớp và phương thức tĩnh. Nếu bạn muốn tìm hiểu sâu hơn về kỹ thuật này, hãy xem Công cụ đơn giản để mô phỏng các lớp bằng cách sử dụng bao đóng và phạm vi lồng nhau (Công thức Python)

Loại bỏ các quảng cáo

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

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

Bạn có thể sử dụng các hàm trang trí để thêm trách nhiệm vào một khả năng gọi được hiện có một cách linh hoạt 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 khả năng gọi ban đầu

Ghi chú. Để biết thêm chi tiết về các đối tượng có thể gọi được trong Python, hãy xem tài liệu về Python và cuộn xuống phần “Các loại có thể gọi được. ”

Để tạo một trình trang trí, bạn chỉ cần xác định một hàm có thể gọi được (một hàm, phương thức hoặc lớp) chấp nhận một đối tượng hàm làm đối số, xử lý nó và trả về một đối tượng hàm 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, bạn có thể áp dụng nó cho bất kỳ chức năng có thể gọi nào. Để làm như vậy, bạn cần sử dụng ký hiệu at (

>>> 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
6) trước tên người trang trí và sau đó đặt nó trên dòng riêng của nó ngay trước tên gọi được trang trí

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

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

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

>>> 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 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
8 làm đối số và xử lý nó trong phần thân của nó. Hoạt động này là một tốc ký cho nhiệm vụ sau đây

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

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

Đây là 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 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í cho
>>> 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 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 ra
>>> def outer_func(who):
..     def inner_func():
..         print(f"Hello, {who}")
..     inner_func()
...

>>> outer_func("World!")
Hello, World!
8, hàm của bạn in ra hai thông báo mới

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

  • gỡ lỗi
  • Bộ nhớ đệm
  • ghi nhật ký
  • thời gian

Một phương pháp phổ biến để gỡ lỗi mã Python là chèn lệnh gọi tớ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."
3 để kiểm tra 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. Việc thêm và xóa các lệnh gọi tớ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."
3 có thể gây khó chịu và bạn có nguy cơ quên một số lệnh gọi đó. Để ngăn chặn tình trạng này, bạn có thể viết một trình 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

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 công cụ trang trí lấy một hàm làm đố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 trình trang trí này để gỡ lỗi các chức năng của mình. Khi bạn nhận được kết quả mong muốn, bạn có thể xóa cuộc gọi 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."
6 và chức năng của bạn sẽ sẵn sàng cho bước tiếp theo

Ghi chú. Nếu bạn muốn tìm hiểu sâu hơn về cách thức hoạt động của

>>> 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."
7 và
>>> 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."
8 trong Python, thì hãy xem Python args và kwargs. làm sáng tỏ

Đây là một ví dụ cuối cùng về cách tạo một trang trí. Lần này, bạn sẽ thực hiện 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 chức năng trang trí

>>>

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

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

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ả giống như bạn nhận được trong quá trình triển khai ban đầu. Trong trường hợp này, bạn sử dụng cả một bao đóng để 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 trang trí trả về một 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
2

Ở đây, trình trang trí cần lấy một đố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), vì vậy bạn cần có hai cấp hàm bên trong lồng nhau. Cấp độ đầu tiên được đại diệ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 đại diện bởi
>>> 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, 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
7, thực hiện phép tính lũy thừa cuối cùng và trả về kết quả

Loại bỏ các quảng cáo

Phần kết luận

Nếu bạn định nghĩa một hàm bên trong một hàm khác, thì bạn đang tạo 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 các hàm trợ giúp, bao đóng và trang trí

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

  • Cung cấp khả năng đóng gói bằng cách lồng các chức năng vào các chức năng khác
  • Viết các hàm trợ giúp để sử dụng lại các đoạn mã
  • Thực hiện các hàm đóng của nhà máy giữ trạng thái giữa các cuộc 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

Bây giờ bạn đã sẵn sàng để tận dụng nhiều cách sử dụng 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 nào, thì hãy nhớ chia sẻ trong phần bình luận bên dưới

Đánh dấu là đã hoàn thành

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

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Xác định chức năng bên trong lớp javascript

Gửi cho tôi thủ thuật Python »

Giới thiệu về Leodanis Pozo Ramos

Xác định chức năng bên trong lớp javascript
Xác định chức năng bên trong lớp javascript

Leodanis là một kỹ sư công nghiệp yêu thích Python và phát triển phần mềm. Anh ấy là một nhà phát triển Python tự học với hơn 6 năm kinh nghiệm. Anh ấy là một nhà văn đam mê kỹ thuật với số lượng bài báo được xuất bản ngày càng tăng trên Real Python và các trang web khác

» Tìm hiểu thêm về Leodanis


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Xác định chức năng bên trong lớp javascript

Aldren

Xác định chức năng bên trong lớp javascript

Derrick

Xác định chức năng bên trong lớp javascript

Geir Arne

Xác định chức năng bên trong lớp javascript

Jim

Xác định chức năng bên trong lớp javascript

Joanna

Xác định chức năng bên trong lớp javascript

Gia-cốp

Xác định chức năng bên trong lớp javascript

Michael

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Chúng ta có thể định nghĩa hàm bên trong lớp trong JavaScript không?

Từ khóa tĩnh trong JavaScript giúp bạn định nghĩa các hàm và thuộc tính trong lớp mà thể hiện của đối tượng không thể gọi được . Chúng chỉ có thể được gọi bởi chính lớp bao gồm các hàm và thuộc tính tĩnh này.

Làm cách nào để gọi một hàm bên trong một lớp trong JavaScript?

Phương thức JavaScript call() . Nó có thể được sử dụng để gọi (gọi) một phương thức với đối tượng chủ sở hữu làm đối số (tham số).

Bạn có thể có một chức năng bên trong một lớp?

Các hàm liên kết với một lớp được gọi là các hàm thành viên của lớp đó. Các hàm thành viên phải được khai báo bên trong lớp nhưng chúng có thể được định nghĩa bên trong lớp hoặc bên ngoài lớp .

Tôi có thể định nghĩa hàm bên trong đối tượng JavaScript không?

Bạn không còn cần chỉ định từ khóa hàm khi xác định hàm bên trong đối tượng . Tùy chọn đầu tiên với các chức năng được đặt tên. const myObj = { myMethod(params) {//. làm gì đó ở đây }, myOtherMethod(params) { //. làm gì đó ở đây }, Obj lồng nhau. { myNestedMethod(params) { //. làm gì đó ở đây } } };