This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
understanding '*' "keyword only" argument notation in python3 functions [duplicate]
(2 answers)
Closed 3 years ago.
While going through the source code, I noticed the following syntax being used in the asyncio library:
#coroutine
def sleep(delay, result=None, *, loop=None):
"""Coroutine that completes after a given time (in seconds)."""
if delay == 0:
yield
return result
if loop is None:
loop = events.get_event_loop()
future = loop.create_future()
h = future._loop.call_later(delay,
futures._set_result_unless_cancelled,
future, result)
try:
return (yield from future)
finally:
h.cancel()
what does the * do in the argument list?
It means that parameter(s) that comes after * are keyword only parameters.
Consider the following:
def test(delay, result=None, *, loop=None):
print(delay, result, loop)
In this case, test(1,2,2) will raise TypeError since it is expecting at most two positional arguments, i.e. delay and result:
test(1,2,2)
TypeError: test() takes from 1 to 2 positional arguments but 3 were given
The third argument, or loop, can only be assigned if used as keyword:
test(1,2,loop=2)
# 1 2 2
# Works fine
For more detail, refer to Function Definitions
Related
This question already has answers here:
Is this an example of python function overload?
(3 answers)
Closed 2 years ago.
I have come across that only parameters at the END of a paramater list can have a default value as VALUES are assigned by position in a function as how it is defined below
def greeting(a,b=7):
pass
and NOT
def greeting(a=4,b):
pass
The doubt which I have in built-in range() function is we can pass the arguments as follows
range(start_value, stop_value, increment_value)
and not all the arguments are needed while calling the function, so is range() function an overloaded function, or does it has default paraments in the definition?
range gets three arguments and it checks count of argument then returns generated iterible object
If you want to do something like it so you shoud replace all arguments with *args then do like following
def range_(*args):
start = 0
end = 0
step = 0
# args is a list of arguments
if len(args) == 1:
end = args[0]
elif len(args) == 2:
start, end = args
elif len(args) == 3:
start, end, step = args
else:
print("the function gets maximum three arguments")
# calculating something with start, end, step
# and return result
P. S.
if you want define function with default arguments then default arguments should be defined before others
This question already has answers here:
Reflect / Inspect closed-over variables in Python
(3 answers)
Closed 3 years ago.
In the following example:
def speak(volume):
def whisper(text):
print(text.lower() + ('.' * volume))
def yell(text):
print (text.upper() + ('!' * volume))
if volume > 1:
return yell
elif volume <= 1:
return whisper
func = speak(volume=10)
func('hello')
HELLO!!!!!!!!!! # <== obviously `10` is stored in `func` somewhere
Given func, how would I get the "volume"? Is there something within the func namespace which gives the value of 10? I thought perhaps it would be in func.__globals__ or func.__dict__ but it's in neither.
Below (the code below return 10)
func.__closure__[0].cell_contents
This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 3 years ago.
I just want to understand why we use *args when the same work can be done by list when we pass it as a argument. In which scenarios do we really need *args, where list as a argument will fail to do that operation.
list =[1,2,3,4,5,6,7]
def method1(args):
for i in args:
print(i*2)
method1(list)
list =[1,2,3,4,5,6,7]
def method1(*args):
for i in args:
print(i*2)
method1(*list)
I didn't find any differences. Please correct me if i am wrong.
def method1(args):
print(args)
method1(5) it will print 5
method1() method1() missing 1 required positional argument: 'args'
method1(2,6) TypeError: method1() takes 1 positional argument but 2 were given
To Avoid this situation we use
def method1(*args):
print(args)
method1(1, 2, '3')
(1, 2, '3') print this
So *args is useful when we don’t know in advance how many arguments we need to pass in.
The difference is that you can pass any number of arguments in the second case where it will throw error in the first case.
Case 1:
lst = [1,2,3,4,5,6,7]
a = 1
b = 2
def method1(args):
for i in args:
print(i*2)
method1(lst, a, b)
...fails with 'TypeError: method1() takes 1 positional argument but 3 were given'.
Case 2 (i):
lst = [1,2,3,4,5,6,7]
a = 1
def method1(*args):
for i in args:
print(i*2)
method1(lst, a)
...works.
Case 2 (ii):
lst = [1,2,3,4,5,6,7]
a = 1
b = 2
def method1(*args):
for i in args:
print(i*2)
method1(lst, a, b)
...works and so on, you can pass any number of arguments.
This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 6 years ago.
Possibly i know the following uses of **
Power
x ** y # x power y equivalent to pow(x,y)
Passing indefinite number of args
def sample(x, **other):
print(x, other.keys)
sample(x=2,y=3,z=4)
But i don't understand when its used as follow( in Serializers)
def create(self, validated_data):
return Comment(**validated_data)
Can someone give me a hint of what is happening there
It is the opposite of your second example. When in the definition of a function, the ** operator gathers all the named arguments and makes a dictionary. When calling a function, it takes a dictionary and breaks it into named arguments
So, if you have
values = {'x': 1, 'y': 2}
f(**values)
it is the equivalent of
f(x=1, y=2)
This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 6 years ago.
What is this star mark in this print function call?
for i in range(int(input())):
s=input()
print(*["".join(s[::2]),"".join(s[1::2])])
It is called argument unpacking. If you were to omit it, then it would only give the list created by the list comprehension to the print function as one argument. With the asterisk it passes every item in that list as separate argument.
Consider this example:
def my_func(arg1, arg2, arg3):
print('yay it worked')
and then call it with:
my_func(*[1, 2, 3])
that way arg1 will be 1, arg2 will be 2 and arg3 will be 3.
If you change the call to:
my_func([1, 2, 3])
then you pass the list to arg1 and it will raise a TypeError because it's missing two positional arguments.