Trang trí phương thức lớp Python

Trình trang trí là các trình bao bọc xung quanh các hàm [hoặc lớp] Python thay đổi cách các lớp này hoạt động. Một trang trí trừu tượng hóa chức năng của chính nó càng xa càng tốt. Ký hiệu Decorator được thiết kế để ít xâm lấn nhất có thể. Nhà phát triển có thể phát triển mã của mình trong miền của mình khi anh ta đã quen và chỉ sử dụng công cụ trang trí để mở rộng chức năng. Bởi vì điều này nghe có vẻ rất trừu tượng, hãy xem xét một số ví dụ

Trong Python, các bộ trang trí được sử dụng chủ yếu để trang trí các hàm [hoặc phương thức tương ứng]. Có lẽ, một trong những decorator được sử dụng phổ biến nhất là

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3 decorator

Như bạn thấy ở dòng cuối cùng, bạn có thể truy cập vào

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
4 của
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
5 của chúng tôi giống như một thuộc tính, tôi. e. , bạn không cần phải gọi phương thức
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
4. Thay vào đó, khi truy cập
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
4 giống như một thuộc tính [không có
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
8], phương thức này được gọi hoàn toàn do trình trang trí
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3

Làm thế nào nó hoạt động?

Viết

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3 trước định nghĩa hàm tương đương với viết
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
1. Nói cách khác.
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
2 là một hàm lấy một hàm khác làm đối số và trả về một hàm thứ ba. Và đây chính xác là những gì người trang trí làm

Do đó, các bộ trang trí thay đổi hành vi của chức năng được trang trí

Viết trang trí tùy chỉnh

Thử lại Trình trang trí

Với định nghĩa mơ hồ đó, hãy viết các bộ trang trí của riêng chúng ta để hiểu cách chúng hoạt động

Giả sử chúng ta có một chức năng mà chúng ta muốn thử lại nếu nó không thành công. Chúng tôi cần một chức năng [trình trang trí của chúng tôi] gọi chức năng của chúng tôi một hoặc hai lần [tùy thuộc vào lần đầu tiên nó có bị lỗi hay không]

Theo định nghĩa ban đầu của chúng tôi về một trình trang trí, chúng tôi có thể viết trình trang trí đơn giản này như thế này

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
0

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
3 là tên của trình trang trí của chúng tôi, nó chấp nhận bất kỳ chức năng nào làm đối số [
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
4]. Bên trong decorator, một hàm mới [
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
5] được xác định và trả về. Thoạt nhìn có thể hơi lạ lẫm khi định nghĩa một hàm bên trong một hàm khác. Tuy nhiên, điều này hoàn toàn ổn về mặt cú pháp và có lợi thế là hàm
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
5 của chúng ta chỉ hợp lệ bên trong không gian tên của trình trang trí
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
3 của chúng ta

Lưu ý rằng trong ví dụ này, chúng tôi đã trang trí chức năng của mình chỉ bằng

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
8. Không có dấu ngoặc đơn [
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
8] sau trang trí
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
8. Do đó, khi gọi hàm
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
91 của chúng tôi, trình trang trí
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
3 được gọi với hàm [
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
93] của chúng tôi làm đối số đầu tiên

Tổng cộng, chúng tôi xử lý ba chức năng ở đây

Trong một số trường hợp, chúng ta cần decorator chấp nhận các đối số. Trong trường hợp của chúng tôi, chúng tôi có thể biến số lần thử lại thành tham số. Tuy nhiên, một trình trang trí phải lấy chức năng trang trí của chúng tôi làm đối số đầu tiên. Hãy nhớ rằng chúng ta không cần gọi decorator khi trang trí một chức năng với nó, tôi. e. chúng tôi vừa viết

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
8 trái ngược với
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
95 trước định nghĩa chức năng được trang trí của chúng tôi

  • Trình trang trí không gì khác hơn là một hàm [chấp nhận một hàm khác làm đối số]
  • Trình trang trí được sử dụng bằng cách đặt nó trước định nghĩa hàm mà không gọi nó

Do đó, chúng ta có thể giới thiệu một hàm thứ tư chấp nhận tham số mà chúng ta muốn làm cấu hình và trả về một hàm thực sự là một hàm trang trí [chấp nhận một hàm khác làm đối số]

Chúng ta hãy cố gắng này

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]

Xé nát cái đó

  • Ở cấp độ đầu tiên, chúng ta có một chức năng gọi là
    import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    3
  • import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    3 chấp nhận một đối số tùy ý [trong trường hợp của chúng ta là ____198] và trả về một hàm
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    99 là hàm được trả về bởi
    import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    3 và là công cụ trang trí thực sự của chúng ta
  • import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    5 hoạt động giống như trước đây [hiện tại nó chỉ tuân theo số lần thử lại tối đa]

Đó là định nghĩa của trang trí của chúng tôi

  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    93 được tô điểm bởi một cuộc gọi hàm lần này, tôi. e.
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    23
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    24 khiến hàm
    import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    3 được gọi và nó trả về trình trang trí thực tế
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    93 cuối cùng được trang trí bởi
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    99 vì chức năng này là kết quả của cuộc gọi
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    24

Đây là một ví dụ khác về một trang trí hữu ích. Hãy tạo một trình trang trí để đo thời gian chạy của các chức năng được trang trí với nó

________số 8

đầu ra

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
9

Như chúng ta thấy, trình trang trí

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
29 thực thi một số mã trước và sau chức năng được trang trí và hoạt động theo cách chính xác như trong ví dụ trước

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
10

Bạn có thể nhận thấy rằng bản thân chức năng

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
5 được trang trí bằng
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
12. Điều này không làm thay đổi logic hoặc chức năng của trình trang trí
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
29 của chúng tôi theo bất kỳ cách nào. Bạn cũng có thể quyết định không sử dụng
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
10

Tuy nhiên, vì trình trang trí

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
15 của chúng tôi cũng có thể được viết là.
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
16, decorator nhất thiết phải thay đổi hàm
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
17 của chúng ta. Đặc biệt, nó thay đổi một số thuộc tính phản xạ ma thuật

  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    18
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    19
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    10
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    11
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    12

Khi sử dụng

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
12, các thuộc tính này được đặt lại về ban đầu

Không có

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
12

Với

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
12

Trang trí lớp học

Cho đến nay, chúng ta chỉ xem xét các bộ trang trí cho các chức năng. Tuy nhiên, cũng có thể trang trí các lớp học

Hãy lấy trình trang trí

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
29 từ ví dụ trên. Hoàn toàn ổn khi bọc một lớp với trình trang trí này như vậy

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
2

Kết quả?

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
1

Vì vậy, rõ ràng là không có thời gian in cho phương pháp

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
17 của chúng tôi. Hãy nhớ rằng ký hiệu
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
18 chỉ tương đương với cách viết
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
19, i. e. , trình trang trí sẽ chỉ được gọi khi bạn “gọi” lớp. Gọi một lớp có nghĩa là khởi tạo nó, vì vậy bộ đếm thời gian chỉ được thực hiện tại dòng
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
30

Các phương thức lớp không được trang trí tự động khi trang trí một lớp. Nói một cách đơn giản, sử dụng một trình trang trí bình thường để trang trí một lớp bình thường trang trí hàm tạo của nó [phương thức

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
31], chỉ

Tuy nhiên, bạn có thể thay đổi toàn bộ hành vi của một lớp bằng cách sử dụng một dạng khác của hàm tạo. Tuy nhiên, trước tiên hãy xem liệu các nhà trang trí có thể làm việc theo cách khác hay không, tôi. e. liệu chúng ta có thể trang trí một chức năng với một lớp. Hóa ra chúng ta có thể

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
1

đầu ra

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3

cách này hoạt động

  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    31 được gọi khi trang trí
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    33. Một lần nữa, hãy nhớ rằng trang trí cũng giống như
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    34
  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    35 được gọi khi một thể hiện của một lớp được sử dụng, giống như gọi một hàm. Vì
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    33 hiện là một phiên bản của
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    37 nhưng chúng tôi vẫn muốn sử dụng nó như một hàm, nên phương thức ma thuật DoubleUnderscore
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    35 chịu trách nhiệm cho việc này

Mặt khác, trang trí một lớp trong Python hoạt động bằng cách thay đổi lớp từ bên ngoài [i. e. , từ người trang trí]

Xem xét điều này

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
4

đầu ra

Một lần nữa, nếu chúng ta tóm tắt lại định nghĩa của một người trang trí, mọi thứ xảy ra ở đây đều tuân theo cùng một logic

  • def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    30 đang gọi người trang trí trước
  • trình trang trí
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    40 vá phương thức
    def retry[max_retries]:
        def retry_decorator[func]:
            def _wrapper[*args, **kwargs]:
                for _ in range[max_retries]:
                    try:
                        func[*args, **kwargs]
                    except:
                        time.sleep[1]
            return _wrapper
        return retry_decorator
    
    
    @retry[2]
    def might_fail[]:
        print["might_fail"]
        raise Exception
    
    
    might_fail[]
    41 cho lớp
  • cuối cùng, lớp được khởi tạo bằng cách sử dụng hàm tạo

Bạn có thể sử dụng các công cụ trang trí để thay đổi các lớp theo cách kế thừa sẽ làm. Nếu đây là một lựa chọn tốt hay không phụ thuộc nhiều vào kiến ​​trúc của toàn bộ dự án Python của bạn. Trình trang trí

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
42 của thư viện tiêu chuẩn là một ví dụ tuyệt vời về cách sử dụng hợp lý khi chọn trình trang trí thay vì kế thừa. Chúng ta sẽ thảo luận về điều đó trong giây lát

sử dụng trang trí

decorators trong thư viện chuẩn của Python

Trong các phần tiếp theo, chúng ta sẽ làm quen với một số decorator phổ biến nhất và hữu ích nhất đã có sẵn trong thư viện chuẩn.

tài sản

Như đã thảo luận, trình trang trí

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3 có lẽ là một trong những trình trang trí được sử dụng phổ biến nhất trong Python. Mục đích của nó là bạn có thể truy cập kết quả của một phương thức giống như một thuộc tính. Tất nhiên, cũng có một bản sao của
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
3 để bạn có thể gọi một phương thức đằng sau hậu trường khi thực hiện một thao tác gán

phương pháp tĩnh

Một decorator quen thuộc khác là

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
45. Trình trang trí này được sử dụng khi bạn muốn gọi một hàm được định nghĩa bên trong một lớp mà không khởi tạo lớp đó

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
2

Khi bạn xử lý các hàm thực hiện một phép tính phức tạp, bạn có thể muốn lưu kết quả của nó vào bộ nhớ cache

Bạn có thể làm một cái gì đó như thế này

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
0

Lưu trữ một biến toàn cục như

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
46, kiểm tra nó để tìm
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
47 và đưa kết quả thực tế vào biến đó nếu không có là các tác vụ lặp đi lặp lại. Điều này làm cho một ứng cử viên lý tưởng cho một trang trí. May mắn thay, có một trình trang trí trong thư viện chuẩn của Python thực hiện chính xác điều này cho chúng tôi

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
1

Bây giờ, bất cứ khi nào bạn gọi

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
48, Python sẽ kiểm tra kết quả được lưu trong bộ nhớ cache trước khi gọi
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
49. Nếu có kết quả trong bộ đệm, thì
def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
49 sẽ không được gọi hai lần

lớp dữ liệu

Trong phần về các bộ trang trí lớp, chúng ta đã thấy rằng các bộ trang trí có thể được sử dụng để sửa đổi hành vi của các lớp giống như cách thừa kế sẽ thay đổi nó

Mô-đun dataclasses trong thư viện chuẩn là một ví dụ điển hình khi sử dụng trình trang trí tốt hơn sử dụng tính kế thừa. Trước tiên hãy xem cách sử dụng

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
21 trong thực tế

Ngay từ cái nhìn đầu tiên, trình trang trí

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
22 chỉ thêm một hàm tạo cho chúng tôi, vì vậy chúng tôi đã tránh mã tấm nồi hơi như thế này

def retry[max_retries]:
    def retry_decorator[func]:
        def _wrapper[*args, **kwargs]:
            for _ in range[max_retries]:
                try:
                    func[*args, **kwargs]
                except:
                    time.sleep[1]
        return _wrapper
    return retry_decorator


@retry[2]
def might_fail[]:
    print["might_fail"]
    raise Exception


might_fail[]
2

Tuy nhiên, nếu bạn quyết định xây dựng một REST-API cho dự án Python của mình và cần chuyển đổi các đối tượng Python thành các chuỗi JSON

Có một gói tên là

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
23 [không có trong thư viện chuẩn] trang trí các lớp dữ liệu và cung cấp khả năng tuần tự hóa và giải tuần tự hóa các đối tượng thành chuỗi JSON và ngược lại

Hãy xem nó trông như thế nào

Có hai điều rút ra ở đây

  1. trang trí có thể được lồng vào nhau. Thứ tự xuất hiện của họ là quan trọng
  2. trình trang trí
    import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    24 đã thêm một phương thức có tên là
    import functools
    import time
    
    def timer[func]:
        @functools.wraps[func]
        def _wrapper[*args, **kwargs]:
            start = time.perf_counter[]
            result = func[*args, **kwargs]
            runtime = time.perf_counter[] - start
            print[f"{func.__name__} took {runtime:.4f} secs"]
            return result
        return _wrapper
    
    @timer
    def complex_calculation[]:
        """Some complex calculation."""
        time.sleep[0.5]
        return 42
    
    print[complex_calculation[]]
    25 vào lớp của chúng tôi

Tất nhiên, chúng ta có thể đã viết một lớp mixin thực hiện công việc nặng nhọc là triển khai một phương thức

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
25 an toàn cho kiểu dữ liệu và sau đó để lớp
import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
27 của chúng ta kế thừa từ mixin đó

Tuy nhiên, trong trường hợp hiện tại, trình trang trí chỉ thêm một chức năng kỹ thuật [trái ngược với phần mở rộng trong miền chủ đề]. Do đó, chúng ta có thể chỉ cần bật và tắt trình trang trí mà ứng dụng miền của chúng ta không thay đổi hành vi của nó. Hệ thống phân cấp lớp “tự nhiên” của chúng tôi được giữ nguyên và không cần thực hiện thay đổi nào đối với mã thực tế. Chúng ta cũng có thể thêm trình trang trí

import functools
import time

def timer[func]:
    @functools.wraps[func]
    def _wrapper[*args, **kwargs]:
        start = time.perf_counter[]
        result = func[*args, **kwargs]
        runtime = time.perf_counter[] - start
        print[f"{func.__name__} took {runtime:.4f} secs"]
        return result
    return _wrapper

@timer
def complex_calculation[]:
    """Some complex calculation."""
    time.sleep[0.5]
    return 42

print[complex_calculation[]]
23 vào dự án mà không thay đổi nội dung phương thức hiện có

Trong trường hợp như vậy, việc thay đổi một lớp bằng một trình trang trí sẽ thanh lịch hơn nhiều [vì nó mang tính mô-đun hơn] so với việc kế thừa hoặc sử dụng mixin

Bạn có thể trang trí các lớp học bằng Python không?

Trong Python, bộ trang trí có thể là hàm hoặc lớp . Trong cả hai trường hợp, trang trí thêm chức năng cho các chức năng hiện có. Khi chúng ta trang trí một hàm với một lớp, thì hàm đó sẽ trở thành một thể hiện của lớp.

Phương thức @class trong Python là gì?

Phương thức của lớp là phương thức được liên kết với lớp chứ không phải đối tượng của lớp . Họ có quyền truy cập vào trạng thái của lớp vì nó nhận tham số lớp trỏ đến lớp chứ không phải thể hiện đối tượng. Nó có thể sửa đổi trạng thái lớp sẽ áp dụng trên tất cả các phiên bản của lớp.

Sự khác biệt giữa @classmethod và Staticmethod là gì?

Phương thức lớp có thể truy cập và sửa đổi trạng thái lớp. Phương thức tĩnh không thể truy cập hoặc sửa đổi trạng thái lớp. Phương thức lớp lấy lớp làm tham số để biết về trạng thái của lớp đó. Các phương thức tĩnh không biết về trạng thái lớp

Chức năng trang trí trong Python là gì?

Trình trang trí trong Python là hàm nhận một hàm khác làm đối số và trả về một hàm khác . Trình trang trí có thể cực kỳ hữu ích vì chúng cho phép mở rộng chức năng hiện có mà không có bất kỳ sửa đổi nào đối với mã nguồn của chức năng ban đầu.

Chủ Đề