Default argument with *args - python

I am new to python and currently learning about functions in python
I created a function which takes all type of argument (normal, *args, default argument, **kwargs)
def func (a, *args, b=3, **kwargs):
print(a)
print(args)
print(b)
print(kwargs)
And to call the fuction i used
func (1, 3,5,4, 5, a=5,j=6)
But default argument value remains same and i don't know how to pass a different value to default parameter 'b'
How can i pass new values to default parameter 'b' in above function??

The parameter *args is your issue.
The special syntax *args in function definitions in python is used to pass a variable number of arguments to a function. It is used to pass a non-key worded, variable-length argument list.
So *args takes all the parameters (since it expects a variable-length list), and b will never receive them. You need to remove *args.

Related

Passing same argument names for a function in Python

In python, I have a class with functions printing certain outputs, of which each has default parameters but those can be changed, like
def func1(self,a='a', b='b'):
return something
def func2(self,c='c', d='d'):
return something
Lots of other functions of a similar kind too.
I created another function that can take those functions with parameters and can do something with them, ie
def foo(self, default,*args,**kwargs):
df=self.df
if default == True:
args = self.list1
else:
for fname in args:
getattr(self, fname)(*kwargs)
df['appending_array'] = df.apply(lambda...
In the effect I'd like to be able to call something like
object.foo(False, func2,func11,d='z')
Unfortunately in the loop, when I change d to 'z', it changes the first argument of each function that is iterated, instead of the actual parameter d from the function I want.
Is there a possibility to either rearrange it so I can pass the original parameters of each passed function, or configure **kwarg so it can refer to the original parameters' names of each function?
Many thanks for any help/advice
So, if I understand correctly, you want to write it such that if, for example, d is present in the foo call, it is solely passed to all functions in args that have d as an input argument (in this case, func2)?
If so, then you want to determine all input arguments that each function can take.
Luckily, Python has a function that allows you to do just that: inspect.signature.
So, you could rewrite it like this (I am assuming you wanted to pass the names of the functions as args, not the actual functions themselves):
from inspect import signature
def foo(self, default, *args, **kwargs):
df=self.df
if default:
args = self.list1
else:
for fname in args:
# Obtain function
func = getattr(self, fname)
# Obtain signature of this function
f_sig = signature(func)
# Create dict with values for this function, updating with values from kwargs
# Make sure to skip 'self'
f_kwargs = {argname: kwargs.get(argname, argpar.default)
for argname, argpar in f_sig.parameters.items()
if (argname != 'self')}
# Call this function
f_out = func(**f_kwargs)
# Perform some operations on the output of this function
df['appending_array'] = df.apply(lambda...
Keep in mind that this only works if every function that is ever passed as args solely takes optional arguments.
If one argument is mandatory, it must be passed to kwargs.
PS: I am however unsure what the use of the args = self.list1 for if default is.
Because that part is incompatible with everything else.
You need to unpack the kwargs with dictionary unpacking using two stars:
getattr(self, fname)(**kwargs)
And I think you also need to provide self as the first argument since these are unbound methods:
getattr(self, fname)(self,**kwargs)

Using the = sign in variables for method calls

When doing a method call in Python, in which cases do you use the = sign when entering arguments?
I noticed sometimes it's:
object.method(argument1 = ... , argument2 = ...)
and other times it's
object.method(... , ...)
Thanks in advance!
That types of arguments are called keyword arguments, probably you've seen that as (kwargs).
In a function you can pass 2 types of args, positional arguments and keyword-arguments.
def function(arg):
So you have to pass inside this function a positional argument, this means that you have to pass only the value for that arg like
function(1) or maybe a string function("hello") or maybe a list and so on; This type of arg is called position arg.
When you have to specify the name of the variable inside the brackets of a function call like function(name = "John"), you are using the keyword args.
If you want to understand more on this topic, i suggest you to see the unpack operator in Python (*) and then *args and **kwargs.
2 words to say what *args and **kwargs do in Python, they allows you to specify an unlimited number of arguments inside a function call.
def function(*args, **kwargs):
pass
function(1,2,3,"hello",[1,2,3],name="John",age=5)

Function parameters, list and int in python

i'm trying to write a function that takes a list and a int as its arguments.
functionName(*args, number)
#do stuff
number needs to be an int but i keep getting a syntax error in IDLE (that's the IDE i'm using)
If your first argument is to be a list, remove the *:
def functionName(listob, number):
The *args syntax is used to catch an arbitrary number of positional arguments and must be listed after all other positional (and keyword) arguments:
def functionName(number, *args):
because it allows your function to be called with just the number, or with any number of extra arguments; functionName(42, 'foo', 'bar') results in number = 42 and args = ('foo', 'bar'). That's not the same as passing in a list object however.
Python doesn't otherwise constrain the types of objects that can be passed in; *args would present extra arguments to your function as a tuple, but only because that's the best way to represent 0 or more arguments extra passed into your function.
You cannot have *args before an actual argument. So you can call it like this:
def foo(name, *args)
However, you want a list, so there's no need for *args. Having the following signature will do just fine:
def foo(name, lst)

What is the "**params" syntax in a Python method definition?

So I am trying out the new python code for the google app engine search library and I came across a weird syntax. This was:
cls_createDocument(**params)
where params was a dictionary.
The function this refers to is:
#classmethod
def _createDocument(
cls, pid=None, category=None, name=None, description=None,
category_name=None, price=None, **params)
My questions is, what does the **params signify and what does that do to the object?
Thanks!
Jon
Consider a function with default arguments:
def func(foo=3):
print(foo)
The structure of the arguments is (in principle) very similar to a dictionary. The function foo has (essentially) a dictionary of default arguments (in this case {'foo':3}). Now, lets say that you don't want to use the keyword in the function call, but you want to use a dictionary instead -- then you can call foo as:
d = {"foo":8}
func(**d)
This allows you to dynamically change what arguments you are passing to the function func.
This become a little more interesting if you try the following:
d = {"foo":8, "bar":12}
func(**d)
This doesn't work (it is equivalent to foo(foo=8, bar=12), but since bar isn't a valid argument, it fails).
You can get around that problem by giving those extra arguments a place to go inside the definition of foo.
def func( foo=3, **kwargs ):
print(foo,kwargs)
Now, try:
d = {"foo":8, "bar":12}
func(**d) #prints (8, {'bar':12})
All the extra keyword arguments go into the kwargs dictionary inside the function.
This can also be called as:
func(foo=8, bar=12)
with the same result.
This is often useful if funcA calls funcB and you want funcA to accept all of the keywords of funcB (plus a few extra) which is a very common thing when dealing with classes and inheritance:
def funcA(newkey=None,**kwargs):
funcB(**kwargs)
Finally, here is a link to the documentation
The **params parameter represents all the keyword arguments passed to the function as a dictionary.

Method with variable number of objects and a list of other arguments

I want to create a method that accepts a variable number of objects and perform some actions(like calling object methods) based on number of other arguments supplied to the method.
e.g. I have an object X with a method updateTable() which accepts a,b as arguments.
What I want to do is that the common code to update table for different objects is placed under a method say updateAllTables().
Is there way to bundle an object and diferent arguments into a structure and supply to the method that accepts variable number of these structures.
To get a Python function to accept an arbitrary number of arguments, just do this:
def my_function(*args, **kwargs):
and now args will be a list of all the positional arguments passed to that function, and kwargs is a dictionary of all the keyword arguments.
Since this is a method, you should probably explicitly accept self outside of the arbitrary args:
def my_method(self, *args, **kwargs):
Variable number of arguments can be sent as list of args (usually denoted by) *args or as a key value pairs **kwargs. You should note that **kwargs should occur after *args if you are passing both.
You can call a method dynamically using using the following syntax getattr(yourobject,'yourfunction')(params,*args,**kwargs)

Categories