This question already has answers here:
How to get method parameter names?
(20 answers)
Closed last month.
Is there an easy way to be inside a python function and get a list of the parameter names?
For example:
def func(a,b,c):
print magic_that_does_what_I_want()
>>> func()
['a','b','c']
Thanks
Well we don't actually need inspect here.
>>> func = lambda x, y: (x, y)
>>>
>>> func.__code__.co_argcount
2
>>> func.__code__.co_varnames
('x', 'y')
>>>
>>> def func2(x,y=3):
... print(func2.__code__.co_varnames)
... pass # Other things
...
>>> func2(3,3)
('x', 'y')
>>>
>>> func2.__defaults__
(3,)
For Python 2.5 and older, use func_code instead of __code__, and func_defaults instead of __defaults__.
locals() returns a dictionary with local names:
def func(a, b, c):
print(locals().keys())
prints the list of parameters. If you use other local variables those will be included in this list. But you could make a copy at the beginning of your function.
If you also want the values you can use the inspect module
import inspect
def func(a, b, c):
frame = inspect.currentframe()
args, _, _, values = inspect.getargvalues(frame)
print 'function name "%s"' % inspect.getframeinfo(frame)[2]
for i in args:
print " %s = %s" % (i, values[i])
return [(i, values[i]) for i in args]
>>> func(1, 2, 3)
function name "func"
a = 1
b = 2
c = 3
[('a', 1), ('b', 2), ('c', 3)]
import inspect
def func(a,b,c=5):
pass
inspect.getargspec(func) # inspect.signature(func) in Python 3
(['a', 'b', 'c'], None, None, (5,))
Related
This question already has answers here:
Local variables in nested functions
(4 answers)
Closed 5 years ago.
I have a situation like the following:
functions = []
some_list = [('a', 'b'), ('c', 'd')]
for x, y in some_list:
def foo(z):
# do some things
return "{} {} {}".format(x, y, z)
functions.append(foo)
But obviously this doesn't work, as x and y will always have the last values they had in the loop, i.e. 'c' and 'd', i.e. both functions in the functions list will return '{} c d'.format(z) in practice.
How do I make it so that it does the string substitution immediately, so that on the first loop it defines foo(z) as the equivalent to
def foo(z):
# do some things
return "{} a b".format(z)
without any reference to the variables x and y?
EDIT: I now realize I also need to store a copy of foo in functions, not foo itself, but the rest of the question stll stands.
You could bind the loop values to local variables at function definition time:
for x, y in some_list:
def foo(z, a=x, b=y):
return "{} {} {}".format(a, b, z)
functions.append(foo)
functions[0]('foo')
'a b foo'
functions[1]('foo')
'c d foo'
I'd like to pass a tuple (or maybe a list) to a function as a sequence of values (arguments). The tuple should be then unpacked as an argument into *arg.
For example, this is clear:
def func(*args):
for i in args:
print "i = ", i
func('a', 'b', 3, 'something')
But what I want to do is this:
tup = ('a1', 'a2', 4, 'something-else')
func(tup)
And this should behave similar to the first case.
I think I should use here reprint and eval but not sure how exactly.
I know that I can just pass the tuple in the function and then unpack it within the body, but my question here is how to unpack it in the function call itself.
You can just use func(*tup) to unpack the tuple directly when you invoke the function.
>>> func(*tup)
i = a1
i = a2
i = 4
i = something-else
This is kind of equivalent to func(tup[0], tup[1], tup[2], ...). The same also works if the function expects multiple individual parameters:
>>> def func2(a, b, c, d):
... print(a, b, c, d)
...
>>> func2(*tup)
('a1', 'a2', 4, 'something-else')
See e.g. here for more in-depth background on the syntax.
You can unpack the tuple during the call by putting a * before the identifier of the tuple. This allows you to easily differentiate between tuples that should be unpacked and ones which shouldn't. This is an example:
>>> MyTuple = ('one', 2, [3])
>>>
>>> def func(*args):
... for arg in args:
... print(arg)
...
>>>
>>> func(*MyTuple)
one
2
[3]
>>>
>>> func(MyTuple)
('one', 2, [3])
You can use *args if you want to unpack your tuple.
Your method definition goes as follows :
def func(*tup):
for i in tup:
print(print "i = ",i)
Now calling your method:
tup = ('a1','a1',4,'something-else')
func(*tup)
Which will yield you the output as-
i = a1
i = a2
i = 4
i = something-else
I'm currently trying to access the arguments of a Python function as strings, because I would like to use these in a naming convention for the output of the function. To start off, I would first like to create a function which simply 'echoes' its arguments (cf. Getting list of parameter names inside python function). I tried this:
import inspect
def echo_arguments(arg1,arg2):
frame = inspect.currentframe()
args, _, _, _ = inspect.getargvalues(frame)
arg1=args[0]
arg2=args[1]
return arg1, arg2
However, if I try to call it, I get this:
>>> (h1,h2)=echo_arguments('hello','world')
>>> h1
'arg1'
>>> h2
'arg2'
In other words, it is returning the 'dummy' arguments from when the function was defined, instead of the 'current' arguments at the time the function is called. Does anybody know how I could get the latter?
Use the locals return by getargvalues:
import inspect
def echo_arguments(arg1,arg2):
frame = inspect.currentframe()
args, _, _, locals_ = inspect.getargvalues(frame)
return (locals_[arg] for arg in args)
Results in:
>>> (h1,h2)=echo_arguments('hello','world')
>>> h1
'hello'
>>> h2
'world'
I would use the ArgInfo object that is returned by inspect.getargvalues(). It includes the argument names as well as the current values in the locals dict.
In [1]: import inspect
In [2]: def foo(a,b=None):
...: frame = inspect.currentframe()
...: args = inspect.getargvalues(frame)
...: return args
In [3]: args = foo(1234,b='qwerty')
In [4]: print args
ArgInfo(args=['a', 'b'], varargs=None, keywords=None, locals={'a': 1234, 'frame': <frame object at 0x072F4198>, 'b': 'qwerty'})
In [5]: print [(arg,args.locals[arg]) for arg in args.args]
[('a', 1234), ('b', 'qwerty')]
All you need to get the contents of those variables is the variables themselves
def echo_arguments(arg1, arg2):
return arg1, arg2
>>> (h1, h2) = echo_arguments('hello', 'world')
>>> h1
'hello'
>>> h2
'world'
I'm trying to accomplish something in Python2.5
So I have my function
def f(a,b,c,d,e):
pass
and now I'd like to call that function: (in python2.7 I would do)
my_tuple = (1,2,3)
f(0, *my_tuple, e=4)
But there is no way to do it in python2.5. I'm thinking about apply()
apply(f, something magical here)
#this doesn't work - multiple value for 'a'. But it's the only thing I came up with
apply(f, my_tuple, {"a":0, "e":4})
How would you do it? I'd like to do it inline, without putting things in list before.
If you're willing to swap the order of arguments then you could use something like this:
>>> def f(a,b,c,d,e):
... print a,b,c,d,e
...
>>> my_tuple = (1,2,3)
>>> def apply(f, mid, *args, **kwargs):
... return f(*args+mid, **kwargs)
...
>>> apply(f, my_tuple, 0, e=4)
0 1 2 3 4
>>>
>>> apply(f, ('a', 'b'), '_', d='c', e='d')
_ a b c d
>>>
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}