I'm making a programming language with Python. I want to be able to run functions by typing:
task $function:
log "Hey!"
and then you can call it by typing:
$function
Right now, I have this code:
def runFunction(self, f):
## Here's where I need help. How will you make a function that runs a function that doesn't exist in
## the code?
...
elif i == 'task':
self.string = line[5:]
self.output = self.string.replace('{', '')
self.function = self.output.replace('}', '')
...
elif i not in self.keywords and '$' in i:
if i == self.function:
self.runFunction(self.function)
What should I do to make a runFunction() function?
What you could do?
You could use python built in function called eval() which lets you evaluate expressions dynamically.
Solution
def runFunction(self, f):
eval(f)
Where f has to be a string
And if you want to create functions:
You could use exec() which can evaluate a string.
Demonstration:
exec("def myFunction(a,b): return a + b")
and use it like
eval("myFunction(1,2)")
How can I call multiple class' methods with a for loop in python? Also, How do I fix the AttributeError so that when I have many more methods, I don't have to write conditional statements to call every method one by one? My code is as follows. Thanks
class Test:
def __init__(self):
def method_1(self, key):
def method_2(self, key):
def method_3(self):
def process(commands):
length = len(commands)
result = []
stack = Test()
for command in commands:
command = command.split()
if len(command) == 2:
# Perform stack.method_1 or stack.method_2
result.append(stack.command[0](command[1])) <====== AttributeError
else:
# Perform stack.method_3
result.append(stack.command) <===== stack has no attribute command
return result
commands = ["method_1 5","method_2 9", "method_3", "method_1 2"]
use getattr function to access the attribute value of an object
for command in commands:
command = command.split()
if len(command) == 2:
# Perform stack.method_1 or stack.method_2
result.append(getattr(stack, command[0])(command[1]))
else:
# Perform stack.method_3
result.append(getattr(stack, command[0])())
return result
What is getattr() exactly and how do I use it?
I declared 3 functions earlier, this is just a goofy text based cookie clicker-esque game.
dostuff={"" : turn() , "help" : helpf() , "invest" : invest() }
while done != True:<br>
do = input("What do you want to do? ")
do = do.lower()
if do == "" or do == "help" or do == "invest":
dostuff[do]
elif do == "quit":
done = True
So when I use dostuff["turn"] it does nothing (the function is supposed to print some things). I have the same problem with the other options.
Your parentheses must be omitted in the dict, and then put at the end of the dict call. You define a function, which becomes a python object. You reference the object with the dict, and then you call the function with the object reference followed by parentheses:
def one():
print("one")
def two():
print("two")
do_stuff = {
"one": one,
"two": two
}
do_stuff["one"]()
prints:
"one"
You can take this concept of executing calls with string inputs a lot farther by familiarizing yourself with the builtin functions of python.
https://docs.python.org/2/library/functions.html
For example, you can create a class and call its methods or properties using text based input with the getattr method:
class do_stuff():
def __init__(self):
pass
def one(self):
print("one")
def two(self):
print("two")
doer = do_stuff()
inp = "one"
getattr(doer, inp)()
prints->
"one"
I am trying to make a menu of options in python where if the user selects a number a different function is executed:
def options(x):
return {
1: f1(),
2: f2()
}[x]
def f1():
print "hi"
def f2():
print "bye"
However, well I call
options(1)
I get:
hi
bye
and same when I call options(2)
What is going on?
You are invoking the functions instead of assiging them against the keys
def f1():
print "hi"
def f2():
print "bye"
functions = {1: f1, 2: f2} # dict of functions (Note: no parenthesis)
def options(x):
return functions[x]() # Get the function against the index and invoke it
options(1)
# hi
options(2)
# bye
Your dictionary is built with the return values of the functions; don't call the function until after picking it from the dict:
def options(x):
return {
1: f1,
2: f2
}[x]()
Now you are storing just a reference to the functions in the dictionary, and call the selected function after retrieving it.
Demo:
>>> def f1():
... print "hi"
...
>>> def f2():
... print "bye"
...
>>> def options(x):
... return {
... 1: f1,
... 2: f2
... }[x]()
...
>>> options(1)
hi
>>> options(2)
bye
Replace print with return and return with, then it will work. Or use thefourtheye version.
The problem is that you call the functions (with ()) while you are building the dictionary. Leave the parens off and apply them later only after getting the value from the dictionary:
def options(x):
return {
1: f1,
2: f2
}[x]()
I am trying to use functional programming to create a dictionary containing a key and a function to execute:
myDict={}
myItems=("P1","P2","P3",...."Pn")
def myMain(key):
def ExecP1():
pass
def ExecP2():
pass
def ExecP3():
pass
...
def ExecPn():
pass
Now, I have seen a code used to find the defined functions in a module, and I need to do something like this:
for myitem in myItems:
myDict[myitem] = ??? #to dynamically find the corresponding function
So my question is, How do I make a list of all the Exec functions and then assign them to the desired item using the a dictionary? so at the end I will have myDict["P1"]() #this will call ExecP1()
My real problem is that I have tons of those items and I making a library that will handle them so the final user only needs to call myMain("P1")
I think using the inspect module, but I am not so sure how to do it.
My reason to avoid:
def ExecPn():
pass
myDict["Pn"]=ExecPn
is that I have to protect code as I am using it to provide a scripting feature within my application.
Simplify, simplify, simplify:
def p1(args):
whatever
def p2(more args):
whatever
myDict = {
"P1": p1,
"P2": p2,
...
"Pn": pn
}
def myMain(name):
myDict[name]()
That's all you need.
You might consider the use of dict.get with a callable default if name refers to an invalid function—
def myMain(name):
myDict.get(name, lambda: 'Invalid')()
(Picked this neat trick up from Martijn Pieters)
Simplify, simplify, simplify + DRY:
tasks = {}
task = lambda f: tasks.setdefault(f.__name__, f)
#task
def p1():
whatever
#task
def p2():
whatever
def my_main(key):
tasks[key]()
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()
# index dictionary by list of key names
def fn1():
print "One"
def fn2():
print "Two"
def fn3():
print "Three"
fndict = {"A": fn1, "B": fn2, "C": fn3}
keynames = ["A", "B", "C"]
fndict[keynames[1]]()
# keynames[1] = "B", so output of this code is
# Two
You can just use
myDict = {
"P1": (lambda x: function1()),
"P2": (lambda x: function2()),
...,
"Pn": (lambda x: functionn())}
myItems = ["P1", "P2", ..., "Pn"]
for item in myItems:
myDict[item]()
This will call methods from dictionary
This is python switch statement with function calling
Create few modules as per the your requirement.
If want to pass arguments then pass.
Create a dictionary, which will call these modules as per requirement.
def function_1(arg):
print("In function_1")
def function_2(arg):
print("In function_2")
def function_3(fileName):
print("In function_3")
f_title,f_course1,f_course2 = fileName.split('_')
return(f_title,f_course1,f_course2)
def createDictionary():
dict = {
1 : function_1,
2 : function_2,
3 : function_3,
}
return dict
dictionary = createDictionary()
dictionary[3](Argument)#pass any key value to call the method
#!/usr/bin/python
def thing_a(arg=None):
print 'thing_a', arg
def thing_b(arg=None):
print 'thing_b', arg
ghetto_switch_statement = {
'do_thing_a': thing_a,
'do_thing_b': thing_b
}
ghetto_switch_statement['do_thing_a']("It's lovely being an A")
ghetto_switch_statement['do_thing_b']("Being a B isn't too shabby either")
print "Available methods are: ", ghetto_switch_statement.keys()
Often classes are used to enclose methods and following is the extension for answers above with default method in case the method is not found.
class P:
def p1(self):
print('Start')
def p2(self):
print('Help')
def ps(self):
print('Settings')
def d(self):
print('Default function')
myDict = {
"start": p1,
"help": p2,
"settings": ps
}
def call_it(self):
name = 'start'
f = lambda self, x : self.myDict.get(x, lambda x : self.d())(self)
f(self, name)
p = P()
p.call_it()
class CallByName():
def method1(self):
pass
def method2(self):
pass
def method3(self):
pass
def get_method(self, method_name):
method = getattr(self, method_name)
return method()
callbyname = CallByName()
method1 = callbyname.get_method(method_name)
```
def p1( ):
print("in p1")
def p2():
print("in p2")
myDict={
"P1": p1,
"P2": p2
}
name=input("enter P1 or P2")
myDictname
You are wasting your time:
You are about to write a lot of useless code and introduce new bugs.
To execute the function, your user will need to know the P1 name anyway.
Etc., etc., etc.
Just put all your functions in the .py file:
# my_module.py
def f1():
pass
def f2():
pass
def f3():
pass
And use them like this:
import my_module
my_module.f1()
my_module.f2()
my_module.f3()
or:
from my_module import f1
from my_module import f2
from my_module import f3
f1()
f2()
f3()
This should be enough for starters.