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

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

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

Construct callable function from string [duplicate]

This question already has answers here:
Calling a function of a module by using its name (a string)
(18 answers)
Closed 5 years ago.
How to construct and call a function from a string?
For example, consider three different functions and a list of strings, I want to be able to use the items in list of strings to construct and call the appropriate function
def do_function1():
return 'done function1'
def do_function2():
return 'done function2'
def do_function3():
return 'done function3'
listOfstr = ['function1','function2','function3']
for item in listOfstr:
result = 'do_'+item()
print(result)
result = 'do_'+item()
TypeError: 'str' object is not callable
The problematic code is
listOfstr = ['function1','function2','function3']
for item in listOfstr:
result = 'do_'+item()
In the first loop item, will have the value 'function1'. You are calling this string as if it were a function. But strings are not callable and have no code assigned to them!
Then, you go on with the for loop before doing anything.
Simply refer to item, like this:
for item in listOfstr:
func_name = 'do_' + item
func = globals()[func_name]
func()
The most explicit way would be to have a dictionary of those functions:
funcs = {
'function1': do_function1,
'function2': do_function2,
'function3': do_function3,
}
funcs[item]()
That way you can also name your functions whatever you want, decouple from item names, make them methods, move to other modules etc without breaking the general design. The other way is globals, as already answered.
First of all, usually you won't need this. Instead of putting strings in a list, you can also put functions themselves in a list like this:
def do_function1():
return 'done function1'
def do_function2():
return 'done function2'
def do_function3():
return 'done function3'
list_of_functions = [do_function1, do_function2, do_function3]
for item in list_of_functions:
result = item()
print(result)
However, if you insist, you can do it like this:
locals()["do_function1"]()
locals() gives you a dictionary of locally defined objects by name.

need a dictionary from another function

If I have a dictionary from another function, how can I pass the dictionary within a new function?
Eg.
From another function, I have tuples like this ('falseName', 'realName', positionOfMistake), eg. ('Milter', 'Miller', 4). I have a function that make a dictionary like this:
D={realName:{falseName:[positionOfMistake], falseName:[positionOfMistake]...},
realName:{falseName:[positionOfMistake]...}...}
def addNameToDictionary(d, tup):
if not d.has_key(tup[0]):
d[tup[0]] = {}
d[tup[0]][tup[1]] = [tup[2]]
Now I need to write a function that takes a list of falseName's and return:
realName:
falseName
falseName
realName:...
My problem is how to call the dictionary from the function addNameToDictionary, to a new function?
I have tried the following:
def Names(nameList):
D=addNameToDictionary(d, tup)
print D
But I get:
NameError: global name 'd' is not defined
Anyone?
def your_new_function(d, falseNames):
# ... get data from d
return {realname:(falseName1, falseName2)}

Why are these lists the same? [duplicate]

This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed 6 months ago.
I can't understand how x and y are the same list. I've been trying to debug it using print statements and import code; code.interact(local=locals()) to drop into various points, but I can't figure out what on earth is going on :-(
from collections import namedtuple, OrderedDict
coordinates_2d=["x","y"]
def virtual_container(virtual_container, objects_type):
"""Used to create a virtual object given a the type of container and what it holds.
The object_type needs to only have normal values."""
if issubclass(virtual_container, list):
class my_virtual_container_class:
"""This singleton class represents the container"""
def __init__(self):
#Define the default values
__vals__=OrderedDict([(key,list()) for key in objects_type])
print(id(__vals__["x"]), id(__vals__["y"]))#ids are different: 12911896 12911968
#Then functions to access them
d={key: lambda self: self.__vals__[key] for key in objects_type}
d["__vals__"]=__vals__
#Construct a named tuple from this
self.attr=type('attr_cl',(), d)()
print(id(self.attr.x()), id(self.attr.y()))#ids are same: 32904544 32904544
#TODO: Define the operators __del__, setitem, getitem. Also append
return my_virtual_container_class()
#Nice method of handling coordinates
coordinates=virtual_container(list, coordinates_2d)
x=coordinates.attr.x()
y=coordinates.attr.y()
x.append(1)
y.append(2)
print(x, y)#Prints [1, 2] [1, 2]
The problem is with this line:
d={key: lambda self: self.__vals__[key] for key in objects_type}
The lambda uses the value of the variable key, but that value has changed by the time the lambda is called - so all lambdas will actually use the same value for the key.
This can be fixed with a little trick: Pass the key as a default parameter value to the lambda:
... lambda self, key=key: self.__vals__[key] ...
This makes sure that the value of key is bound to the one it had at the time the lambda was created.
I think the following line should look like this (but unfortunately I can't test because I don't have Python 3 available):
# Then functions to access them
d = dict((key, lambda self: self.__vals__[key]) for key in objects_type)

Categories

Resources