Cách sử dụng đối số có độ dài thay đổi (* args, ** kwargs) trong Python

Kinh doanh

Các đối số hàm sau đây có lẽ là những đối số phổ biến nhất khiến bạn bối rối khi nhìn vào mã Python và nói, “Đây là cái gì?

  • *args
  • **kwargs

Bất kỳ số lượng đối số nào (đối số có độ dài thay đổi) có thể được chỉ định bằng cách thêm dấu hoa thị vào đối số trong định nghĩa hàm như sau

  • *
  • **

Các tên * args, ** kwargs thường được sử dụng như một quy ước. Tuy nhiên, các tên khác có thể chấp nhận được với điều kiện là * và ** ở đầu. Mã mẫu sau sử dụng các tên * args, ** kwargs.

Các chi tiết sau đây được mô tả dưới đây.

  • *args:Chấp nhận nhiều đối số dưới dạng một bộ
  • **kwargs:Chấp nhận nhiều đối số từ khóa như một từ điển

*args:Chấp nhận nhiều đối số dưới dạng một bộ

Có thể chỉ định số lượng đối số tùy ý bằng cách xác định đối số bằng *, như trong * args.

def my_sum(*args):
    return sum(args)

print(my_sum(1, 2, 3, 4))
# 10

print(my_sum(1, 2, 3, 4, 5, 6, 7, 8))
# 36

Nhiều đối số được nhận dưới dạng một bộ trong hàm. Trong ví dụ, hàm sum () được chuyển qua một bộ giá trị để tính tổng.

def my_sum2(*args):
    print('args: ', args)
    print('type: ', type(args))
    print('sum : ', sum(args))

my_sum2(1, 2, 3, 4)
# args:  (1, 2, 3, 4)
# type:  <class 'tuple'>
# sum :  10

Nó cũng có thể được kết hợp với một đối số vị trí.

Giá trị được chỉ định sau (ở bên phải) đối số vị trí được chuyển tới args dưới dạng một bộ giá trị. Nếu chỉ có một đối số vị trí, nó là một bộ giá trị rỗng.

def func_args(arg1, arg2, *args):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

func_args(0, 1, 2, 3, 4)
# arg1:  0
# arg2:  1
# args:  (2, 3, 4)

func_args(0, 1)
# arg1:  0
# arg2:  1
# args:  ()

Các đối số được đánh dấu bằng * có thể được xác định trước. Tuy nhiên, trong trường hợp này, các đối số được xác định sau * args phải được chỉ định ở dạng từ khóa. Ngẫu nhiên, định dạng từ khóa là dạng “tên đối số = giá trị”.

Giá trị cuối cùng không được tự động chuyển đến đối số vị trí. Do đó, nếu nó không được chỉ định làm đối số từ khóa, thì sẽ xảy ra lỗi TypeError.

def func_args2(arg1, *args, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

# func_args2(0, 1, 2, 3, 4)
# TypeError: func_args2() missing 1 required keyword-only argument: 'arg2'

func_args2(0, 1, 2, 3, arg2=4)
# arg1:  0
# arg2:  4
# args:  (1, 2, 3)

Nếu chỉ các đối số * được chỉ định, các đối số tiếp theo phải luôn được chỉ định làm đối số từ khóa.(keyword-only argument)

def func_args_kw_only(arg1, *, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)

# func_args_kw_only(100, 200)
# TypeError: func_args_kw_only() takes 1 positional argument but 2 were given

func_args_kw_only(100, arg2=200)
# arg1:  100
# arg2:  200

**kwargs:Chấp nhận nhiều đối số từ khóa như một từ điển

Có thể chỉ định số lượng tùy ý của các đối số từ khóa bằng cách xác định các đối số với, ** như trong ** kwargs.

Trong hàm, tên của đối số được nhận dưới dạng từ điển có khóa là khóa và giá trị của đối số là giá trị.

def func_kwargs(**kwargs):
    print('kwargs: ', kwargs)
    print('type: ', type(kwargs))

func_kwargs(key1=1, key2=2, key3=3)
# kwargs:  {'key1': 1, 'key2': 2, 'key3': 3}
# type:  <class 'dict'>

Nó cũng có thể được sử dụng cùng với một đối số vị trí.

def func_kwargs_positional(arg1, arg2, **kwargs):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('kwargs: ', kwargs)

func_kwargs_positional(0, 1, key1=1)
# arg1:  0
# arg2:  1
# kwargs:  {'key1': 1}

Bằng cách chỉ định đối tượng từ điển với ** làm đối số khi gọi hàm, có thể mở rộng đối tượng và chuyển nó làm đối số tương ứng.

d = {'key1': 1, 'key2': 2, 'arg1': 100, 'arg2': 200}

func_kwargs_positional(**d)
# arg1:  100
# arg2:  200
# kwargs:  {'key1': 1, 'key2': 2}

Các đối số được đánh dấu bằng ** chỉ có thể được xác định ở cuối đối số. Việc xác định đối số khác sau đối số được đánh dấu bằng ** sẽ dẫn đến lỗi SyntaxError.

# def func_kwargs_error(**kwargs, arg):
#     print(kwargs)

# SyntaxError: invalid syntax
Copied title and URL