Programmatically get function arguments (without **kwargs)? [duplicate] - python

This question already has answers here:
Get a list/tuple/dict of the arguments passed to a function?
(8 answers)
Closed 5 years ago.
Given the following function:
def test(* p1=None, p2=None):
...
Called as follows:
test(p2="hello")
Can I programmatically obtain a list/dictionary of the arguments and their value at runtime?
1: Don't want to use **kwargs because I want to force the user to use the proper argument names (and plan to do type annotation as well).
2: I've looked at the inspect module for getting the defaults, but does not seem to let me see the run-time values.
Looking to create code something like this:
request = {k: v for k,v in __some_magic_location__ if v is not None}

Use locals:
>>> def test(*, p1=None, p2=None):
... return locals()
...
>>> test(p2='hello')
{'p1': None, 'p2': 'hello'}

You can use inspect.getcallargs:
import inspect
def test(*, p1=None, p2=None):
pass
print(inspect.getcallargs(test, p2 = 'Hello'))
Output:
{'p2': 'Hello', 'p1': None}

Related

Do stuff with variable that has the same name of a string [duplicate]

This question already has answers here:
How to use string value as a variable name in Python? [duplicate]
(3 answers)
How do I create variable variables?
(17 answers)
Closed 4 years ago.
let's say I have a variable called "x" and a string that has the value of "x" (string1 = "x"). How do I do stuff with the variable through the string?
For example change the variable's value or call a method if it's an object?
Thanks in advance
Variables are available through dictionaries locals() and globals(). If you want to access a particular variable by it's spring name, you can do e.g.
>>> my_var = 'hello'
>>> x = 'my_var'
>>> locals()[x]
'hello'
You can also assign back to the variable using this approach, e.g.
>>> my_var = 'hello'
>>> x = 'my_var'
>>> locals()[x] = 'something else'
>>> my_var
'something else'
Since functions are objects in Python, you can access any locally available functions in the same manner to call them.
>>> def my_test_function(n):
>>> return n*8
Accessing the method and calling it.
>>> locals()['my_test_function'](4)
32
For accessing attributes of objects by their name you can use getattr(), and setattr() to set them. For example, creating an object with a single property called your_prop.
class Example:
your_prop = 2
a = Example()
The value is available via your_prop.
>>> a.your_prop
2
The property can be accessed via name using getattr
>>> getattr(a, 'your_prop')
2
The property can be set using setattr:
>>> setattr(a, 'your_prop', 5)
>>> a.your_prop
5
Ok, let's suppose that you have lots of different functions: Aoo(), Boo(), Coo()... and let's suppose that you want to specify which of them to call via command line argument.
Now, that argument will be a string, so you need to call a function through its name, but you do not know in advance the name of the function.
One possible solution is to use exec():
def boo():
print("boo function")
def coo():
print("coo function")
Now:
argument = "boo"
exec(argument + "()")
>>> boo function
and
argument = "coo"
exec(argument + "()")
>>> coo function
It depends what you're trying to do, but you can scoop up whatever x is pointing to with locals() or globals():
def x(k):
return k + 1
string1 = "x"
the_function_x = locals()[string1]
print(the_function_x(3))
outputs 4 (it called the x function by utilizing string1).

How to call a function using dictionary key Value? [duplicate]

This question already has answers here:
Is there a way to store a function in a list or dictionary so that when the index (or key) is called it fires off the stored function?
(3 answers)
Closed 4 years ago.
Here I am trying to call a function using dictionary key value.
>>> def hello():
print('hello')
>>> a = {'+': hello()}
it just prints hello after executing this line.
>>> a['+']
If I call the dictionary using key value, it results nothing. What am I missing here?
Do not put () while you are using the function name as a value for the dictionary because as soon as python find () it will execute the function.
Instead just add the function name a = {'+': hello}
And then use the () while fetching the value from the dictionary
a["+"]()
You need a return call.
def hello():
return 'hello'
Or I think that is what you want
You should put your callable as the value into the dict and then call it.
>>> def hello():
print('hello')
>>> a = {'+': hello}
>>> a['+']()
hello

python select a function based on the value in a dictionary [duplicate]

This question already has answers here:
Calling a function of a module by using its name (a string)
(18 answers)
Closed 6 years ago.
I want to select a function based on the value of a dictionary:
dict = {"func_selector":"func1", "param_value":"some_value"}
# defined a function
def func1(param):
# some function code
Now, I want to select the function based on the value of some key, so that it can achieve something like:
# calling a function based on some dict value
dict["func_selector"](dict["param_value"])
The syntax is probably wrong, but I am wondering if it is possible to do that in Python or something similar.
Try storing the value of the function in the dictionary, instead of its name:
def func1(param):
print "func1, param=%r" % (param,)
d = {"func_selector":func1, "param_value": "some value"}
Then you can say:
>>> d['func_selector'](d['param_value'])
func1, param='some value'
The best approach IMO is do it like this
def func1(param):
#code
some_value = ... #The value you need
my_dict = {"func_selector": func1, "param_value": some_value }
And then
my_dict["func_selector"](my_dict["param_value"])
Now, if you only have the name of the function you need to call getattr
And call it
getattr(my_class, my_dict["func_selector"])(my_dict["param_value"])
my_class is the class which contains the method. If it's not in a class I think you can pass self

Print an object's attributes like json.dumps prints a dict [duplicate]

This question already has answers here:
Is there a built-in function to print all the current properties and values of an object?
(30 answers)
Closed 7 years ago.
EDIT: a solution is in this answer: How to use a dot “.” to access members of dictionary?
When using a dict:
d = dict()
d['param1'] = 17
d['param2'] = 3
it's easy to print it with print json.dumps(d). When using an object / class:
class z:
pass
z.param1 = 17
z.param2 = 3
I can't manage to print all the attributes of z, neither with print json.dumps(z), nor with print z. How to do it?
Sidenote but important: why do I want to use a class / object to store parameters, when it would be logical to use a dict? Because z.param1 is much shorter and handy to write than z['param1'], especially with my (french) keyword [, ], 'are quit long to write because ALT+GR+5 (let's say 2 seconds instead of 0.5, but this really matters when you have a long code with many variables)
You may simply use __dict__ on a class instance to get the attributes in the form of dict object as:
>>> z.__dict__
>>> {'param1': 17, '__module__': '__main__', 'param2': 3, '__doc__': None}
However, if you need to remove the __xxx__ inbuilt methods then you may need to specify the __str__ method inside the class.

Python: dict default argument... how did I not know they work like this? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument
class Klass(object):
def a(self, d={}):
print d
self.b(d)
def b(self, d={}):
import random
print d
d[str(random.random())] = random.random()
I assumed that every time I call c.a() without arguments, I got a fresh empty dict. However, this is what actually happens:
>>> c = Klass()
>>> c.a()
{}
{}
>>> c.a()
{'0.637151613258': 0.61491180520119226}
{'0.637151613258': 0.61491180520119226}
>>> c.a()
{'0.637151613258': 0.61491180520119226, '0.960051474644': 0.54702415744398669}
{'0.637151613258': 0.61491180520119226, '0.960051474644': 0.54702415744398669}
...
I don't really want to do some sort of lambda/iscallable thing. What is a good pattern to use here?
Of course, I figured out I decent way around the problem by the time I had started typing out the question. But, if anyone has a different pet way around this, I would love to hear.
Could get a fresh, empty dict with:
def a(self, d=None):
if d is None:
d = {}
The problem is well described here under Mutable Default Arguments.

Categories

Resources