Trang trí python vs chức năng

Bất kỳ sản phẩm ứng dụng nào xuất hiện có thể sẽ có một số hướng dẫn về cách thức và những gì cần phải đăng nhập vào ứng dụng của bạn. Thông thường, các hướng dẫn này xuất phát từ các mô hình công nghiệp chung như ký hiệu nhật ký của tất cả các ngoại lệ. Tuy nhiên, việc thực hiện các hướng dẫn này là để quay lại các nhà phát triển riêng lẻ và dẫn đến cùng một bộ báo cáo ghi nhật ký được lặp lại trong suốt cơ sở mã. Ví dụ, để ghi nhật ký tất cả các trường hợp ngoại lệ, bạn sẽ có một lệnh ghi nhật ký trong mỗi khối

def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
9 cú bắt ngoại lệ và ghi nhật ký theo cấp độ
>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
0. Nhưng tuyên bố ghi nhật ký cho cùng một kịch bản có thể khác nhau giữa các nhà phát triển do phong cách phát triển cá nhân của họ. Làm thêm giờ Điều này dẫn đến việc đăng nhập phân đoạn và không quán nhất trong ứng dụng. Hơn nữa, các nhà phát triển có thể phạm sai lầm và bỏ lỡ tuyên bố đăng nhập tại những nơi cần thiết

Một cách tiếp cận để giảm thiểu vấn đề này là sử dụng tính năng trang trí Python. Bài viết này sẽ cung cấp một cái nhìn tổng quan ngắn gọn về các nhà trang trí và quá trình diễn ra cách tạo ra một nhà trang trí để hiển thị các đối tượng tuyên bố khai thác gỗ phổ biến này. Bạn có thể đọc thêm về trang trí và theo nhiều cách mà chúng có thể được sử dụng trong cách tuyệt vời này trên trang trí Python

Man page is anything

Một người trang trí là một chức năng có chức năng khác và mở rộng hành vi của nó mà không cần phải sửa đổi rõ ràng của nó. Chúng còn được gọi là chức năng cấp cao

Các chức năng của Python là những công dân hạng nhất. Điều này có nghĩa là các chức năng có thể được thông qua như đối số hoặc có thể là chủ đề của nhiệm vụ. Vì vậy, nếu bạn có chức năng

>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
1, bạn có thể sử dụng nó như bất kỳ đối tượng nào khác và đi sâu vào các thuộc tính của nó.
def sum[a, b=10]:
    return a+b
>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']

Vì các chức năng hoạt động như một đối tượng, bạn có thể chỉ định

>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
2 cho một chức năng khác. Sau đó, call
>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
2 sẽ gọi chức năng này thay vì cái mà chúng tôi đã xác định trước đó. Các trang trí vị trí sử dụng hành động này bằng cách gán_______12 một hàm mới lấy_______12 làm tham số và kết thúc một số logic bổ sung xung quanh nó do đó mở rộng nó mà không cần sửa đổi chức năng

def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
2____03

Mô hình này phổ biến đến mức Python có cú pháp để trang trí một chức năng. Vì vậy, thay vì

_______ 16, chúng ta có thể sử dụng ký hiệu _______ 17 trên đầu phương thức
>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
2 như thế này -
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
7

Ghi nhật ký trang trí

Chúng tôi sẽ tạo ra một trang trí xử lý hai kịch bản ghi nhật ký phổ biến - các ngoại lệ ghi nhật ký là đối số phương thức lỗi và ghi nhật ký dưới dạng ký tự sửa lỗi

Please start by the way gius Capture the exceptions and register it by Python library

>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
9.
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
9
>>> test  [  a = 1, b = 4, c = 'blah-blah' ]
test  [  a = 1, b = 3, c = 'blah-blah' ]
test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
0

Other setting

def sum[a, b=10]:
    return a+b
0, chúng tôi cũng đã sử dụng @functools. kết thúc tốt đẹp. Bộ trang trí
def sum[a, b=10]:
    return a+b
1 cập nhật chức năng
def sum[a, b=10]:
    return a+b
2 trông giống như
def sum[a, b=10]:
    return a+b
3. Công cụ trang trí ______34 của chúng tôi hiện có thể được sử dụng trên bất kỳ chức năng nào để bắt mọi ngoại lệ từ chức năng được bọc và đăng nhập nó một cách quán nhất

Vì hàm

def sum[a, b=10]:
    return a+b
2 chấp nhận tất cả các đối số [
def sum[a, b=10]:
    return a+b
6], bộ trang trí _
def sum[a, b=10]:
    return a+b
4 có thể được mở rộng để nắm bắt tất cả các tham số được truyền cho chức năng được trang trí. Chúng ta có thể làm điều này chỉ bằng cách lặp lại trên các đối số và kwarg và tham gia của chúng để tạo chuỗi thông báo vào nhật ký.
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
0
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
1

Chúng tôi đăng nhập các tham số ở cấp độ giảm thiểu lỗi vì chúng tôi không muốn đăng ký của chúng tôi lộn ngược với tất cả các tham số chức năng. Ghi nhật ký có thể được chuyển đổi trên các hệ thống của chúng tôi khi cần thiết. Hãy nhớ rằng điều này sẽ ghi tất cả các giá trị đối số vào nhật ký bao gồm mọi dữ liệu hoặc bí mật PII. Hãy nhớ rằng điều này sẽ ghi tất cả các giá trị đối số vào nhật ký bao gồm mọi dữ liệu PII hoặc bí mật

Bộ trang trí khai thác cơ bản này có vẻ tốt và đã làm những gì chúng tôi đặt ra ban đầu để đạt được. Miễn phí là một phương pháp được trang trí với

def sum[a, b=10]:
    return a+b
4, chúng tôi sẽ ghi lại bất kỳ ngoại lệ nào được nêu trong đó và tất cả các đối số được truyền cho nó

Tuy nhiên, trong một dự án thực sự,

def sum[a, b=10]:
    return a+b
0 có thể được ghi đối tượng hóa vào lớp của chính nó để khởi tạo một trình ghi nhật ký dựa trên cấu hình định sẵn nhất [không hạn chế như đăng nhập vào một đám mây]. Trong trường hợp này, vô dụng để đăng nhập vào bảng điều khiển bằng cách tạo bộ ghi nhật ký của chúng tôi trong bộ trang trí _
def sum[a, b=10]:
    return a+b
4. Chúng tôi cần một cách để chuyển
def sum[a, b=10]:
    return a+b
0 hiện vào trang trí người của chúng tôi trong thời gian chạy. Để làm điều này, chúng tôi có thể mở rộng người trang trí ______34 để chấp nhận
def sum[a, b=10]:
    return a+b
0 như một cuộc tranh luận

To started this script, we will started with a layer create ra một bộ ghi âm cho chúng ta. Bây giờ chúng ta sẽ tạo bộ ghi âm cơ bản nhưng bạn có thể tưởng tượng lớp cấu hình hành động của logger theo yêu cầu

def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
2

Vì tại thời điểm người viết trang trí, chúng tôi không biết liệu chức năng cơ bản sẽ vượt qua chúng tôi

>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']
4 hoặc
>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']
5 hay không có logger nào, người trang trí chung của chúng tôi sẽ có thể xử lý tất cả chúng.
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
3

Mã trên trông khá đáng sợ nhưng hãy để tôi tóm tắt nó. Nhà trang trí

def sum[a, b=10]:
    return a+b
4 hiện xử lý ba kịch bản khác nhau -
  • No logger any information through. Đây là kịch bản tương tự những gì chúng tôi đã làm cho đến trước đó. Bộ trang trí đơn giản chỉ được sử dụng làm tuyên bố

    >>> test  [  a = 1, b = 4, c = 'blah-blah' ]
    test  [  a = 1, b = 3, c = 'blah-blah' ]
    test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
    test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
    
    24 on start function. Trong trường hợp này, người trang trí nhận được một logger bằng cách gọi phương thức
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    8 và sử dụng nó cho phần còn lại của phương thức. Đây là kịch bản tương tự những gì chúng tôi đã làm cho đến trước đó. Trình trang trí được sử dụng đơn giản là câu lệnh as
    def sum[a, b=10]:
        return a+b
    
    4 ở đầu hàm. Trong trường hợp này, người trang trí lấy một logger bằng cách gọi phương thức ____48 và sử dụng nó cho phần còn lại của phương thức
  • >>> test  [  a = 1, b = 4, c = 'blah-blah' ]
    test  [  a = 1, b = 3, c = 'blah-blah' ]
    test  [  a = 1, b = 4, c = 'blah-blah', kwargs = {'d': 5} ]
    test  [  a = 1, b = 2, c = 3, args = [4, 5], kwargs = {'d': 6, 'g': 12.9} ]
    
    64 was information through. Công cụ trang trí _
    def sum[a, b=10]:
        return a+b
    
    4 của chúng tôi hiện có thể chấp nhận ví dụ
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4 làm đối số. Sau đó, nó có thể gọi phương thức
    def dumpArgs[func]:
        '''Decorator to print function call details - parameters names and effective values'''
        def wrapper[*func_args, **func_kwargs]:
            arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
            args = func_args[:len[arg_names]]
            defaults = func.func_defaults or []
            args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
            params = zip[arg_names, args]
            args = func_args[len[arg_names]:]
            if args: params.append[['args', args]]
            if func_kwargs: params.append[['kwargs', func_kwargs]]
            print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
            return func[*func_args, **func_kwargs]
        return wrapper  
    
    @dumpArgs
    def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
        pass
    
    test[1]
    test[1, 3]
    test[1, d = 5]
    test[1, 2, 3, 4, 5, d = 6, g = 12.9]
    
    22 để tạo một bộ ghi chép xen kẽ và sử dụng phần còn lại của nó. Trình trang trí ______34 của chúng tôi hiện có thể chấp nhận phiên bản của
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4 làm đối số. Sau đó, nó có thể gọi phương thức
    def dumpArgs[func]:
        '''Decorator to print function call details - parameters names and effective values'''
        def wrapper[*func_args, **func_kwargs]:
            arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
            args = func_args[:len[arg_names]]
            defaults = func.func_defaults or []
            args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
            params = zip[arg_names, args]
            args = func_args[len[arg_names]:]
            if args: params.append[['args', args]]
            if func_kwargs: params.append[['kwargs', func_kwargs]]
            print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
            return func[*func_args, **func_kwargs]
        return wrapper  
    
    @dumpArgs
    def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
        pass
    
    test[1]
    test[1, 3]
    test[1, d = 5]
    test[1, 2, 3, 4, 5, d = 6, g = 12.9]
    
    22 để tạo bộ ghi nhật ký lồng nhau và sử dụng phần còn lại của nó
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
4
  • >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    5 was information through. Trong kịch bản thứ ba này, chúng ta có thể vượt qua bản ghi chính thay vì vượt qua lớp
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4. Trong trường hợp thứ ba này, chúng ta có thể chuyển chính bộ ghi nhật ký thay vì chuyển lớp
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
5

Chúng tôi vẫn chưa hoàn thành. Ngay cả trong hình thức hiện tại của chúng tôi, tôi trang trí log của chúng tôi bị giới hạn chế độ. Một giới hạn chế độ là chúng ta phải có sẵn

def sum[a, b=10]:
    return a+b
0 hoặc
>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']
4 trước phương pháp chúng ta muốn trang trí. Nói cách khác, tham chiếu đến logger phải tồn tại trước khi phương thức tồn tại. Điều này có thể hoạt động trong trường hợp chức năng đích là một phần của Lớp và phương pháp Lớp
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
27 có thể khởi động việc tạo logger, nhưng nó đã thành công với các chức năng bên ngoài cảnh của Lớp. Trong nhiều ứng dụng trong thế giới thực, chúng tôi sẽ không có từng mô-đun hoặc chức năng tạo ra logger của riêng họ. Thay vào đó, chúng tôi có thể muốn chuyển bộ ghi vào chức năng.
def sum[a, b=10]:
    return a+b
0 hoặc
>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']
4 sẽ được đưa vào các nguồn phương pháp hạ áp. Nói cách khác, một hàm có thể có bộ ghi được truyền cho nó trong tham số của nó

Nhưng if function is an part of layer thì

def sum[a, b=10]:
    return a+b
0 sẽ được đưa vào lớp và không vào mọi phương pháp của lớp. Trong trường hợp này, chúng tôi sẽ muốn sử dụng logger có sẵn cho lớp của chúng tôi để thay thế

Vì vậy, mục tiêu của chúng tôi là bắt giữ

def sum[a, b=10]:
    return a+b
0 đã được thông qua như là lập luận cho chức năng được trang trí hoặc được chuyển đổi cho chức năng tạo lớp của chức năng được trang trí của chúng tôi và sử dụng nó để đăng nhập từ bộ trang chính. Bằng cách thực hiện điều này, người trang trí của chúng tôi có thể được tách rời hoàn toàn khỏi bộ ghi chính và sẽ sử dụng bất kỳ logger nào có sẵn cho phương pháp cơ bản trong thời gian chạy. hoặc được chuyển đến hàm tạo lớp của hàm được trang trí của chúng tôi và sử dụng nó để ghi nhật ký từ chính trình trang trí. Bằng cách này, trình trang trí của chúng tôi có thể được tách rời hoàn toàn khỏi chính trình ghi nhật ký và sẽ sử dụng bất kỳ trình ghi nhật ký nào có sẵn cho phương thức cơ bản khi chạy

Để làm điều này, chúng tôi sẽ lặp lại các đối số

def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
32 và
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
33 và kiểm tra xem chúng tôi có nhận được
def sum[a, b=10]:
    return a+b
0 trong bất kỳ ai trong số họ không. Để kiểm tra xem hàm này có phải là một phần của lớp không, chúng ta có thể kiểm tra xem đối số đầu tiên của ______032 có thuộc tính
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
36 không. Nếu đối số đầu tiên có thuộc tính
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
36, chúng tôi sẽ lặp lại trên
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
38 và kiểm tra xem một trong những giá trị này có phải là logger của chúng tôi không. Cuối cùng, nếu không có gì hoạt động, chúng tôi sẽ mặc định theo phương thức
>>> sum

>>> sum.__code__.co_varnames  # Names of local variables
['a', 'b']
8.
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
6

Người trang trí trên đủ chung chung để làm việc cho 2 kịch bản nữa ngoài 3 kịch bản chúng ta đã thảo luận trước đây -

  • def sum[a, b=10]:
        return a+b
    
    0 hoặc
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4 được chuyển sang phương pháp trang trí
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
7
  • Hoặc
    def sum[a, b=10]:
        return a+b
    
    0 hoặc
    >>> sum
    
    >>> sum.__code__.co_varnames  # Names of local variables
    ['a', 'b']
    
    4 được chuyển đến phương pháp
    def dumpArgs[func]:
        '''Decorator to print function call details - parameters names and effective values'''
        def wrapper[*func_args, **func_kwargs]:
            arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
            args = func_args[:len[arg_names]]
            defaults = func.func_defaults or []
            args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
            params = zip[arg_names, args]
            args = func_args[len[arg_names]:]
            if args: params.append[['args', args]]
            if func_kwargs: params.append[['kwargs', func_kwargs]]
            print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
            return func[*func_args, **func_kwargs]
        return wrapper  
    
    @dumpArgs
    def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
        pass
    
    test[1]
    test[1, 3]
    test[1, d = 5]
    test[1, 2, 3, 4, 5, d = 6, g = 12.9]
    
    27 lưu trữ chức năng được trang trí
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
8

Một điều bổ sung mà chúng tôi đã làm là bọc tất cả các mã trước khi gọi hàm được trang trí

def sum[a, b=10]:
    return a+b
3 trong khối
def dumpArgs[func]:
    '''Decorator to print function call details - parameters names and effective values'''
    def wrapper[*func_args, **func_kwargs]:
        arg_names = func.func_code.co_varnames[:func.func_code.co_argcount]
        args = func_args[:len[arg_names]]
        defaults = func.func_defaults or []
        args = args + defaults[len[defaults] - [func.func_code.co_argcount - len[args]]:]
        params = zip[arg_names, args]
        args = func_args[len[arg_names]:]
        if args: params.append[['args', args]]
        if func_kwargs: params.append[['kwargs', func_kwargs]]
        print func.func_name + ' [' + ', '.join['%s = %r' % p for p in params] + ' ]'
        return func[*func_args, **func_kwargs]
    return wrapper  

@dumpArgs
def test[a, b = 4, c = 'blah-blah', *args, **kwargs]:
    pass

test[1]
test[1, 3]
test[1, d = 5]
test[1, 2, 3, 4, 5, d = 6, g = 12.9]
76. Chúng tôi không muốn thực hiện thất bại các vấn đề trong việc đăng nhập ngay cả trước khi chức năng đích được gọi. Trong mọi trường hợp logic ghi nhật ký của chúng tôi sẽ gây ra lỗi trong hệ thống

Kết luận

Bộ định vị trên là một điểm khởi đầu tốt và có thể được mở rộng hoặc đơn giản hóa theo các yêu cầu. Nó làm giảm khả năng bỏ lỡ việc ghi nhật ký ngoại lệ và chuẩn hóa các thông báo lỗi trong suốt ứng dụng

Tiếp cận với tôi trong các ý kiến ​​​​dưới đây cho bất kỳ câu hỏi nào mà bạn có thể có

Trang định vị Python có thể lấy tranh luận không?

Các đối số trang trí có thể truy cập được cho bộ trang trí bên trong thông qua việc đóng, giống như cách chức năng bên trong gói [] có thể truy cập f. Và vì việc đóng cửa mở rộng đến tất cả các cấp của các hàm bên trong, ARG cũng có thể truy cập được từ bên trong Wrapping [] nếu cần thiết. , chính xác như cách hàm bên trong wrap[] có thể truy cập f. Và vì các bao đóng mở rộng đến tất cả các cấp độ của các hàm bên trong, nên arg cũng có thể truy cập được từ bên trong wrap[] nếu cần.

Ưu điểm lớn nhất của người trang trí trong Python là gì?

Một người trang trí trong Python là một chức năng lấy một chức năng khác làm cho các đối số của nó và trả về một chức năng khác. Các 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 chức năng ban đầu. cho phép mở rộng chức năng hiện có mà không cần sửa đổi mã nguồn ban đầu của chức năng .

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

Trình trang trí là một mẫu thiết kế trong Python cho phép người dùng bổ sung chức năng mới vào một đối tượng hiện có mà không cần sửa đổi cấu trúc của nó. Thường thì trang trí được gọi trước khi định nghĩa về một chức năng bạn muốn trang trí. mẫu thiết kế trong Python cho phép người dùng thêm chức năng mới vào đối tượng hiện có mà không sửa đổi cấu trúc của đối tượng

Chủ Đề