*_ and *args assigns which value at runtime | python | - python

Not getting internally what is happening. *_ amd *args doing
what is assigned to default() at runtime
Using *_ in default
def default(*_):
return "Not Happy"
a,b=10,20
default(a,b)
Using *args in default
def default(*args):
return "Not Happy"
a,b=10,20
default(a,b)
I am trying to understand what is assigned to default at runtime.
if not a and b
I have used website to see visually what happens at runtime during execution but not getting : https://pythontutor.com/visualize.html

In Python, you can define variadic functions (i.e. functions that can take any number of arguments), cf the tutorial or a RealPython article about it.
The gist of it is that you can declare a *whatever parameter, and Python will collect the variadic parameters and put them in there for you. For example :
>>> def foo(*args):
>>> print(type(args), args)
>>>
>>> foo()
<class 'tuple'> ()
>>> foo(1)
<class 'tuple'> (1,)
>>> foo(1, 'a')
<class 'tuple'> (1, 'a')
>>> foo(1, 'a', 'b', 'c')
<class 'tuple'> (1, 'a', 'b', 'c')
The convention is to call it args, but you can give it another name :
>>> def foo(*elephant):
>>> print(elephant)
>>>
>>> foo(1, 'a')
(1, 'a')
So when you call default(a,b), then *args (or *_ if you want) is filled, and you can use it in your function :
>>> def default(*args):
>>> return "Not Happy" + str(args)
>>>
>>> a,b=10,20
>>> default(a,b)
'Not Happy(10, 20)'
default is a function, when you do default(...) you call that function, meaning you execute the code you wrote in it. You are passing a and b, none of them is listed as a regular parameter, so both ends up in the *args parameter.

Related

Python: Accept multiple arguments

In Python I am trying to make a function that can accept 1 or more arguments. For simplicity let's say I want to make a function that prints all the arguments that are passed
def print_all(**arguments**):
print(arg1, arg2, ..., argN)
so print_all("A", "B") would output AB.
The number of arguments passed could be 1 or more strings.
What is the best way to do this?
*args and **kwargs allow to pass any no of arguments, positional (*) and keyword (**) to the function
>>> def test(*args):
... for var in args:
... print var
...
>>>
For no of variable
>>> test("a",1,"b",2)
a
1
b
2
>>> test(1,2,3)
1
2
3
For list & dict
>>> a = [1,2,3,4,5,6]
>>> test(a)
[1, 2, 3, 4, 5, 6]
>>> b = {'a':1,'b':2,'c':3}
>>> test(b)
{'a': 1, 'c': 3, 'b': 2}
For detail
Simply this:
def print_all(*args):
for arg in args:
print(arg)
Use the splat operator (*) to pass one or more positional arguments. Then join them as strings in your function to print the result.
def print_all(*args):
print("".join(str(a) for a in args))
>>> print_all(1, 2, 3, 'a')
123a
You are looking for the usage of *args which allows you to pass multiple arguments to function without caring about the number of arguments you want to pass.
Sample example:
>>> def arg_funct(*args):
... print args
...
>>> arg_funct('A', 'B', 'C')
('A', 'B', 'C')
>>> arg_funct('A')
('A',)
Here this function is returning the tuple of parameters passed to your function.
For more details, check: What does ** (double star) and * (star) do for parameters?

Is there a way to get function parameter names, including bound-methods excluding `self`?

I can use inspect.getargspec to get the parameter names of any function, including bound methods:
>>> import inspect
>>> class C(object):
... def f(self, a, b):
... pass
...
>>> c = C()
>>> inspect.getargspec(c.f)
ArgSpec(args=['self', 'a', 'b'], varargs=None, keywords=None, defaults=None)
>>>
However, getargspec includes self in the argument list.
Is there a universal way to get the parameter list of any function (and preferably, any callable at all), excluding self if it's a method?
EDIT: Please note, I would like a solution which would on both Python 2 and 3.
inspect.signature excludes the first argument of methods:
>>> from inspect import signature
>>> list(signature(c.f).parameters)
['a', 'b']
You could also delete the first element of args manually:
from inspect import ismethod, getargspec
def exclude_self(func):
args = getargspec(func)
if ismethod(func):
args[0].pop(0)
return args
exclude_self(c.f) # ArgSpec(args=['a', 'b'], ...)

Automatically remove named parameters from a Python function call

I've written a Python library that uses a lot of named parameters in its function calls, and I'm wondering if there's any way to automatically remove all of these named parameters, instead of removing them manually (which is a very tedious task).
For example, would it be possible to translate this function call:
getClass(lang="Java", body=[
mainMethod(lang="Java", body=[
println(lang="Java", toPrint="Hello World")
])
])
into the function call below (which omits the named arguments, and is much more concise?):
getClass("Java", [
mainMethod("Java", [
println("Java", "Hello World!")
])
])
In order to do this, one possible approach would be to write a function that would print its own function call as a string - however, I don't think it's possible to write a function that would do this. Are there any other approaches to this problem that might work as well?
There is no need. Keyword arguments can still be passed positionally. There is the added benefit, here, of being able to specify one or none of them, if you would so please. However, you don't need to specify any at all.
>>> def foo(bar=1, baz=[2,3]):
... print bar, baz
...
>>> foo()
1 [2, 3]
>>> foo(baz=4)
1 4
>>> foo(10, 20)
10 20
If I'm misunderstanding the code you're providing, let me know. Steve's answer seems to indicate that you are actually working with strings, but I didn't see anything in your post to indicate that.
You did mention a function which prints its own function call; by this, I assume you mean that the function must print a string which looks exactly like the thing you'd type to call the function with the same arguments which you passed. This is relatively easy to do, because you can either type the function's name as-is, or you can use its __name__ attribute.
>>> def goo(a,b):
... print "{}({}, {})".format(goo.__name__, a, b)
...
>>> goo(1,2)
goo(1, 2)
>>> def hoo(*args):
... print "{}({})".format(hoo.__name__, ', '.join((str(arg) for arg in args)))
...
>>>
>>> hoo(2,3,4,5)
hoo(2, 3, 4, 5)
Thinking about it, your example seems wanting of a general function which would grant this behavior to any function - recursively. Here's a way to achieve that, using partials (I'll redefine foo() so that the example makes some more sense):
>>> from functools import partial
>>> def foo(a, b):
... return (a if not isinstance(a, partial) else a()) + (b if not isinstance(b, partial) else b())
...
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> fun()
15
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> def print_pfunc(pfunc):
... return "{}({}{}{})".format(pfunc.func.__name__, ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args) if pfunc.args else '', ', ' if pfunc.args and pfunc.keywords else '', ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords) if pfunc.keywords else '')
...
>>> print print_pfunc(fun)
foo(1, foo(foo(2, 4), foo(3, 5)))
If you're not a fan of that very long format() call, here's a different way to write it (just so that you don't have to spend time decoding my garbage):
def print_pfunc(pfunc):
args = ""
if pfunc.args is not None:
args = ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args)
kwargs = ""
if pfunc.keywords is not None:
kwargs = ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords)
return "{}({}{}{})".format(pfunc.func.__name__, args, ', ' if args and kwargs else '', kwargs)
Adapting this to your code, now, will require you to write code which will turn your function calls into partials before evaluating them. It's up to you what you want to do from this point - I can't think of a clever way to get around the fact that function calls passed as arguments get evaluated before they are passed, as this will interfere with what you are trying to do.

what is the asterisk in "replace(*something)" for? (python) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does *args and **kwargs mean?
I' just reading Mining the social web and encountered a python syntax that I can't figure out:
transforms = [(', Inc.', ''), (', Inc', ''), (', LLC', ''), (', LLP', '')]
"google, Inc.".replace(*transforms[0])
But if I type
*transforms[0]
in the interpreter, it says it is invalid syntax. I googled it, but the python docu really is not up for the job.
So what does the asterisk means here please? Thank you all.
The *argument format in python means: use all elements in the sequence argument and pass them as arguments to the function.
In this specific case, that translates to:
"google, Inc.".replace(', Inc.', '')
This is easiest demonstrated:
>>> def foo(arg1, arg2):
... print arg1, arg2
...
>>> arguments = ('spam', 'eggs')
>>> foo(*arguments)
spam, eggs
You can also use the **kw double star format to pass in keyword arguments:
>>> def foo(arg1='ham', arg2='spam'):
... print arg1, arg2
...
>>> arguments = dict(arg2='foo', arg1='bar')
>>> foo(**arguments)
bar, foo
and you can use the same spelling in a function definition to capture arbitrary positional and keyword arguments:
>>> def foo(*args, **kw):
... print args, kw
...
>>> foo('arg1', 'arg2', foo='bar', spam='eggs')
('arg1', 'arg2'), {'foo': 'bar', 'spam': 'eggs'}
The asterisk unpacks an iterable. I think it is best explained with an example:
>>> def exampleFunction (paramA, paramB, paramC):
print('A:', paramA)
print('B:', paramB)
print('C:', paramC)
>>> myTuple = ('foo', 'bar', 'baz')
>>> myTuple
('foo', 'bar', 'baz')
>>> exampleFunction(myTuple)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
exampleFunction(myTuple)
TypeError: exampleFunction() takes exactly 3 arguments (1 given)
>>> exampleFunction(myTuple[0], myTuple[1], myTuple[2])
A: foo
B: bar
C: baz
>>> exampleFunction(*myTuple)
A: foo
B: bar
C: baz
As you can see, we defined a function that takes three arguments and a tuple with three elements. Now if we want to use the values from the tuple directly, we cannot just pass the tuple and have it working. We could pass each element separately but that is just very verbose. What we do instead is use the asterisk to unpack the tuple and essentially use the elements from the tuple as arguments.
There is a second usage for the unpacking functionality when working with a unknown number of parameters:
>>> def example2 (*params):
for param in params:
print(param)
>>> example2('foo')
foo
>>> example2('foo', 'bar')
foo
bar
>>> example2(*myTuple)
foo
bar
baz
The asterisk allows us here to define a parameter that takes all the remaining values that were passed and packs it into an iterable, so we can iterate it.
It turns the tuple passed into a list of arguments. So
"google, Inc.".replace(*transforms[0])
becomes
"google, Inc.".replace(', Inc.', '')
This way you can programatically construct the list of arguments that are being passed (with variable length being a key advantage).
Check section 4.7.4 of the Python tutorial: http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions
But if I type
*transforms[0]
in the interpreter, it says it is invalid syntax.
The * in front of transforms[0] only has meaning in a function call.
An alternative way of making this call with the data in the first tuple in the list is:
"Google, Inc.".replace(transforms[0][0],transforms[0][1])

Find out the number of arguments passed to a function consisting of default values for arguments in python

Consider the following python function:
def fun(x=0,y=1,z=1):
print x,y,z
fun(2)
Is there a way i can find out within the function how many arguments were actually passed to it,which in the above case is 1 ?
Please Help
Thank You
Have a look at the inspect module
import inspect
inspect.getargspec(someMethod)
Get the names and default values of a Python function’s arguments. A tuple of four things is returned: (args, varargs, keywords, defaults). args is a list of the argument names (it may contain nested lists). varargs and keywords are the names of the * and ** arguments or None. defaults is a tuple of default argument values or None if there are no default arguments; if this tuple has n elements, they correspond to the last n elements listed in args.
>>> def fun(x=0,y=1,z=1):
... print x,y,z
...
>>> func = fun
>>> func.func_code.co_argcount
3
>>> func.func_code.co_varnames
('x', 'y', 'z')
You can also try inspect module
>>> import inspect
>>> inspect.getargspec(func).args
['x', 'y', 'z']
>>> inspect.getargspec(func)
ArgSpec(args=['x', 'y', 'z'], varargs=None, keywords=None, defaults=(0, 1, 1))
Are you looking something like:
def fun(**kwargs):
arg_count = len(kwargs)
print("Function called with",arg_count,"arguments")
params = {"x": 0, "y": 1, "z":1} #defaults
params.update(kwargs)
print("Now arguments are", params, )
fun(x=2)
Output:
Function called with 1 arguments
Now arguments are {'y': 1, 'x': 2, 'z': 1}

Categories

Resources