Python allows us to define three types of arguments for a function:
Python允许我们为函数定义三种类型的参数:
def add(a, b)
def add(a, b)
def add(*args)
def add(*args)
def add(**kwargs)
.def add(**kwargs)
。Some important points about function arguments.
有关函数参数的一些重要点。
Let’s say we have a function to add two numbers:
def add_two_numbers(a, b):
return a + b
Now we want to extend this to add three numbers. We can’t just change this function because it might be getting used at some other places and it will be a breaking change. So, we introduce another function to add three numbers.
def add_three_numbers(a, b, c):
return a + b + c
You see where I am going with this, right? Since we have the option to specify a variable number of arguments for a function, we can define a generic function to add numbers.
Let’s define a generic function to add numbers using *args variables.
def add(*args):
total = 0
for arg in args:
total = total + arg
return total
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 2, 3, 4))
def zap(*args, **kwargs):
print(type(args))
print(type(kwargs))
zap()
Output:
Let’s define a function to show the usage of **kwargs variables.
def kwargs_processor(**kwargs):
for k, v in kwargs.items():
print(f'Key={k} and Value={v}')
kwargs_processor(name='Pankaj', age=34)
kwargs_processor(country='India', capital='New Delhi')
Output:
Key=name and Value=Pankaj
Key=age and Value=34
Key=country and Value=India
Key=capital and Value=New Delhi
Let’s see how to pass tuple values to map with args and dictionary elements to the kwargs variable.
t = (10, 30, 60)
print(add(*t))
d = {'name': 'Pankaj', 'age': 34}
kwargs_processor(**d)
Output:
100
Key=name and Value=Pankaj
Key=age and Value=34
Notice the use of * while using a tuple to map its values to args. Similarly, ** is used to map dict elements to the kwargs variable.
You can use them in any function where you are expecting a variable number of arguments. However, they are very useful in two specific cases – Simulating a function response, and writing a generic decorator function.
Let’s say we have an API class defined like this:
class APIHelper:
def call_api(self, url, input_json):
# some complex logic
return 'complex_response_data'
We can create a test simulator function and map it to the API function to generate a test response.
class MyTestClass:
def test_call_api(self, *args, **kwargs):
return "test_response_data"
# Assign API function to use our test function
APIHelper.call_api = MyTestClass.test_call_api
Let’s see what happens when we use our API functions now.
ah = APIHelper()
print(ah.call_api())
print(ah.call_api(1, url='https://www.journaldev.com', input_json={}))
print(ah.call_api(1, 2, url='https://www.journaldev.com'))
Output:
test_response_data
test_response_data
test_response_data
Let’s see how we can define a decorator function to log function variables.
def log_arguments(func):
def inner(*args, **kwargs):
print(f'Arguments for args:{args}, kwargs:{kwargs}')
return func(*args, **kwargs)
return inner
Now, we can use this decorator function with any other function to log their arguments to console.
@log_arguments
def foo(x, y, z):
return x + y + z
sum_ints = foo(1, 2, z=5)
print(sum_ints)
@log_arguments
def bar(x, *args, **kwargs):
total = x
for arg in args:
total = total + arg
for key, value in kwargs.items():
total = total + value
return total
sum_ints = bar(1, 2, 3, a=4, b=5)
print(sum_ints)
Output:
Arguments for args:(1, 2), kwargs:{'z': 5} 8 Arguments for args:(1, 2, 3), kwargs:{'a': 4, 'b': 5} 15