This question already has answers here:
Can a variable number of arguments be passed to a function?
(6 answers)
Closed 4 years ago.
I am trying to make my function be able to accept as many inputs or as little inputs as needed.
Currently I have 3 inputs that are hard coded (loc1, loc2, loc3). Is there a way to keep the inputs variable so if I just had 1 input, or if I have 5 inputs, my function can be flexible?
def np_array(loc1, loc2, loc3):
loc_a = np.array(loc1)
loc_b = np.array(loc2)
loc_c = np.array(loc3)
pressure_vector1 = np.subtract(loc_a, loc_c)
pressure_vector2 = np.subtract(loc_a, loc_b)
movement_vector = np.add(pressure_vector1, pressure_vector2)
return movement_vector
You can use *args or **kwargs for this.
In Python, the single-asterisk form of *args can be used as a parameter to send a non-keyworded variable-length argument list to functions. It is worth noting that the asterisk (*) is the important element here, as the word args is the established conventional idiom, though it is not enforced by the language.
The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks (**) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.
Like *args, **kwargs can take however many arguments you would like to supply to it. However, **kwargs differs from *args in that you will need to assign keywords.
To learn more about this I recommend this awesome post
You could use default arguments to make the function more flexible like:
def np_array(loc1=None, loc2=None, loc3=None):
# ensure you don't use None type variables
if loc1 is None:
loc1 = 'sensibleDefaultValueGoesHere'
# repeat as often as needed before you proceed with the
# actual calculation ...
Related
This question already has answers here:
Why use positional only arguments in python 3.8?
(1 answer)
Mandatory keywords arguments
(2 answers)
Closed 11 months ago.
Python has support for postional only and keyword only arguments
Positional only arguments
def postional_only_func(a,b,/):
...
Keyword only arguments
def keyword_only_func(*,a,b):
...
But, what are its practical use case when writing a function? Is it just to make code more readable?
Both of these features were added to make writing certain functions easier. IF you want to read the full rational and motivation, you should read the corresponding PEPs:
PEP 570 – Python Positional-Only Parameters
PEP 3102 – Keyword-Only Arguments
For positional only, here are concrete examples for use-cases, using examples from the built-in functions:
There are functions with other interesting semantics:
range(), an overloaded function, accepts an optional parameter to the left of its required parameter. [4]
dict(), whose mapping/iterator parameter is optional and semantically must be positional-only. Any externally visible name for
this parameter would occlude that name going into the **kwarg keyword
variadic parameter dict. [3]
One can emulate these semantics in Python code by accepting (*args,
**kwargs) and parsing the arguments manually. However, this results in a disconnect between the function definition and what the function
contractually accepts. The function definition does not match the
logic of the argument handling.
And for keyword-only arguments it says the following regarding motivation:
There are often cases where it is desirable for a function to take a
variable number of arguments. The Python language supports this using
the ‘varargs’ syntax (*name), which specifies that any ‘left over’
arguments be passed into the varargs parameter as a tuple.
One limitation on this is that currently, all of the regular argument
slots must be filled before the vararg slot can be.
This is not always desirable. One can easily envision a function which
takes a variable number of arguments, but also takes one or more
‘options’ in the form of keyword arguments. Currently, the only way to
do this is to define both a varargs argument, and a ‘keywords’
argument (**kwargs), and then manually extract the desired keywords
from the dictionary.
This question already has answers here:
What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
(25 answers)
Closed 6 years ago.
This is a basic question. Is there a difference in doing
def foo(*args, **kwargs):
"""standard function that accepts variable length."""
# do something
foo(v1...vn, nv1=nv1...nvn=nvn)
def foo(arg, kwargs):
"""convention, call with tuple and dict."""
# do something
mytuple = (v1, ..vn)
mydict = {nv1=nv1, ...nvn=nvn}
foo(mytuple, mydict)
I could do the same thing with both, except that the later has a weird convention of creating a tuple and dictionary. But basically is there a difference? I can solve the same computational problem of handling infinite things because dict and tuple can take care of that for me anyway?
Is this more of an idiomatic part of Python i.e a good Syntactic Sugar for things that you do anyway? I.e function is going to handle this for you!
PS: Not sure of so many downvotes though I agree this is a copy of Why use packed *args/**kwargs instead of passing list/dict? and probably it should be corrected in the duplicate information. And that question has recieved upvotes. So am I being downvotes for not being able to find that?
args and kwargs are just names.
What really matters here is the * and **.
In your second example you can only call the function with 2 arguments, against the first example where you can call the function with basically infinite arguments.
This question already has answers here:
Is there a way to pass optional parameters to a function?
(5 answers)
Closed 7 years ago.
I'm making a Script with a GUI Box in a CAD program, and the User selects about 7 different surfaces in the viewport. I then pass those values onto another Function when the User hits "OK"
The function that it is passed to looks like this
def MeshingTools(od_idSurf, trgSurf, PipeBodySurf, sealSurf, threadSurf, BodySurf, cplgEndSurf):
The problem is: if the user does not need to select one of those surfaces, I get a error saying, MeshingTools() takes exactly 7 non-keyword arguments (2 given)
How can I get around this issue?
UPDATE:
I tried keyword arguments and am not quite getting what I need.
def MeshingTools(**kwargs):
print kwargs
When I just select 1 surface, I get the following out
{'PipeBodySurf': (mdb.models['FullCAL4'].rootAssembly.instances['PinNew-1'].edges[151], mdb.models['FullCAL4'].rootAssembly.instances['PinNew-1'].edges[153])}
if I try to print PipeBodySurf , it says that global name is not defined.
Any ideas?
FINAL UPDATE (SOLVED)
Now I see that **kwargs creates a dictionary, so instead of using just the parameter name in the rest of the code, you have to use kwargs['parameter'] and then it will use the values
You can use arbitrary argument passing with * operation :
def MeshingTools(*args):
for i in args:
#do stuff with i
Functions can use special argument preceded with one or two * character to collect an arbitrary number of extra arguments. (* for positional arguments and ** for keyword arguments)
This question already has answers here:
Can a variable number of arguments be passed to a function?
(6 answers)
Closed 8 years ago.
How do you write a function in Python with variable arguments into the function and return variable number of outputs? Is this even possible with the constraints?
You mean like this. This is quite similar to ellipses in Java. When supplied with a variable amount of arguments, you can unpack these arguments as a list which you can manipulate as you deem necessary.
def func(*args):
print len(args) # num of vars
yes you can, take a look at splat operator
def my_function(*a): #here a will be list or tuple depend wt u passed
# do your stuff with a
**a for dictionary
This question already has answers here:
Proper way to use **kwargs in Python
(14 answers)
Closed 8 years ago.
With keyword arguments, you can't just reference potential keyword values in the dict, since they may not be present. What's the best way to reference keyword values that may or may not be there? I find myself doing things like this:
def save_link(link, user, **kwargs):
if "auto" in kwargs:
auto = kwargs["auto"]
else:
auto = False
in order to provide default values and create a variable that is reliably present. Is there a better way?
You may use the get property of dict:
auto = kwargs.get('auto', False)
This allows for using a default value (Falsein this case).
However, please be quite careful with this approach, because this kind of code does not complain about wrong keyword arguments. Someone calls funct(1,2,auot=True) and everything looks ok. You might consider checking that the kwargs you receive belong to some certain list.