Using a dictionary to select function to execute
Not proud of it, but:
def myMain(key):
def ExecP1():
pass
def ExecP2():
pass
def ExecP3():
pass
def ExecPn():
pass
locals()['Exec' + key]()
I do however recommend that you put those in a module/class whatever, this is truly horrible.
If you are willing to add a decorator for each function, you can define a decorator which adds each function to a dictionary:
def myMain(key):
tasks = {}
def task(task_fn):
tasks[task_fn.__name__] = task_fn
@task
def ExecP1():
print(1)
@task
def ExecP2():
print(2)
@task
def ExecP3():
print(3)
@task
def ExecPn():
print(4)
tasks['Exec' + key]()
Another option is to place all the functions under a class (or in a different module) and use getattr
:
def myMain(key):
class Tasks:
def ExecP1():
print(1)
def ExecP2():
print(2)
def ExecP3():
print(3)
def ExecPn():
print(4)
task = getattr(Tasks, 'Exec' + key)
task()
Calling a function in program from a dictionary
As a very simplified demo of what it you are attempting to do, look at the following:
def northOfHouse():
print "north"
action = raw_input()
myDict[action]()
def westOfHouse():
print "west"
action = raw_input()
myDict[action]()
myDict = {
"WEST": westOfHouse,
"NORTH": northOfHouse
}
action = raw_input()
myDict[action]()
First I've defined 2 functions (northOfHouse
and westOfHouse
). Each of this functions will simply print there location and ask for a new input. They will then attempt to call the function for the given input in the dictonary.
Next I define the dictionary, in my case using the keys "WEST"
and "NORTH"
to reference the correct functions(note that I'm not calling the functions). These can then be called using the appropriate myDict["WEST"]()
or myDict["NORTH"]()
as you would expect.
Using this it's possible to enter "NORTH"
and "WEST"
and see the appropriate function being called, this can obviously be expanded to what you want to do (with the inclusion of appropriate input validation and performing these instructions on a loop basis rather than recursively of course as with the code provided, recursion depth errors will haunt you after too long).
Another thing I'd recommend is to return a dictionary from each function, that way the current location determines where you can move to next:
def northOfHouse():
print "You're in the NORTH of the house\nYou can go 'WEST'"
myDict = {
"WEST": westOfHouse
}
return myDict
def westOfHouse():
print "You're in the WEST of the house\nYou can go 'NORTH'"
myDict = {
"NORTH": northOfHouse
}
return myDict
currentMoves = northOfHouse()
while 1:
action = raw_input()
if(action in currentMoves):
currentMoves = currentMoves[action]()
else:
print "Invalid Input"
Try Here on repl.it
Using dictionary to select function to run
You are calling the functions while declaring the dict. You also forgot to call you function at the end with ()
.
Try this:
def set_race(self, race):
race_list = {
"Dragonborn": self.character_race.select_dragonborn,
"Dwarf": self.character_race.select_dwarf,
"Elf": self.character_race.select_elf,
"Gnome": self.character_race.select_gnome,
"Half-Elf": self.character_race.select_halfelf,
"Halfling": self.character_race.select_halfling,
"Half-Orc": self.character_race.select_halforc,
"Human": self.character_race.select_human,
"Tiefling": self.character_race.select_tiefling
}
race_list[race]()
Call a function when it is stored as dictionary value
Simply call dic['c']()
to run your function. Hope I helped!
Python dict to select function runs all of them
You're not storing your execute
function in your options
dict. You're storing the result of calling that function. And since it's the same function either way with different parameters being passed in, you don't actually need the function to be the values in your dict. You need the parameters. Change your last four lines to:
options = {
"BACKUP": [self.jobtype, self.src, self.dst],
"RESTORE": [self.jobtype, self.dst, self.src],
}
execute(*options[jobtype])
Calling functions with parameters using a dictionary in Python
I would do this using functools.partial
to specify the arguments when the dictionary is created:
from functools import partial
options = {0: FunctionZero,
1: FunctionOne,
2: FunctionTwo,
3: partial(FunctionThree, True)}
Note that this also allows additional parameters to be passed when the function is called (as long as all the functions in the dictionary have the same parameters missing after partial
has been called):
def test(one, two, three=None, four=None):
...
def test2(one, two, three=None):
...
options = {1: partial(test, 1, three=3, four=4),
2: partial(test2, 1, three=3)}
...
options[choice](2) # pass the 'two' argument both functions still require
Dictionary value as function to be called when key is accessed, without using ()
Another possible solution, is to create a custom dictionary object that implements this behavior:
>>> class CallableDict(dict):
... def __getitem__(self, key):
... val = super().__getitem__(key)
... if callable(val):
... return val()
... return val
...
>>>
>>> d = CallableDict({1: "A", 2: "B", 3: lambda: print('run')})
>>> d[1]
'A'
>>> d[3]
run
A perhaps more idiomatic solution would be to use try/except
:
def __getitem__(self, key):
val = super().__getitem__(key)
try:
return val()
except TypeError:
return val
Note however the method above is really for completness. I would not reccomend using it. As pointed out in the comments, it would mask TypeError
's raised by the function. You could test the exact content of TypeError
, but at that point, you'd be better of using the LBYL style.
Related Topics
What Is the Most Compatible Way to Install Python Modules on a MAC
Flask-Sqlalchemy Import/Context Issue
Print Current Call Stack from a Method in Code
Unbuffered Stdout in Python (As in Python -U) from Within the Program
Except-Clause Deletes Local Variable
Memory-Efficient Built-In SQLalchemy Iterator/Generator
How to Import Data from Mongodb to Pandas
Web Scraping Program Cannot Find Element Which I Can See in the Browser
Print Statement Inside of Input Returns with a "None"
Use Groupby in Pandas to Count Things in One Column in Comparison to Another
How to Use Type Hints in Python 3.6
List Comprehension and Lambdas in Python
Pandas Sum by Groupby, But Exclude Certain Columns
Getting Values from Object Oriented Tkinter
How to Represent an Infinite Number in Python