Reputation: 1227
Lets say I have a python program that is a black box and that acts like a processor. It reads a text file with some instruction names, parses this file and calls the functions from a class Instructions. What I want is to allow the user to create new functions in another file, and allow the processor to call these functions via the Instructions class.
Example processor code (cannot change this):
from instructions import *
instr = Instructions()
code = []
with open('program.txt') as f:
code = f.readlines()
for line in code:
command, args = line.split()
# reads "command arg" and calls "instr.command(arg)"
string_exec = 'instr.{}({})'.format(command, args)
eval(string_exec)
Example instructions.py:
class Instructions:
def show(self, arg):
print(arg, end='')
Example of 'program.txt' that the processor reads to print "Hello":
show 'H'
show 'e'
show 'l'
show 'l'
show 'o'
show '\n'
I want to be able to read a file from the user with new instructions and be able to execute them in the processor.
Example of user function that also uses the instructions:
def print_line(self, args):
for arg in args:
instr.show(arg)
instr.show('\n')
I want to incorporate the user functions into the class Intructions somehow, such that the processor can be able to run the following 'program.txt':
print_line 'Hello'
In short, I want to divide the Instructions functions in two files, one with some basic 'fixed' instructions, and the other with 'dynamic' functions the user defines. At the end I want to load both functions in the class Instructions.
Upvotes: 2
Views: 3593
Reputation: 88
instructions.py like this:
class Instructions:
def __init__(self):
self._add_user_function()
def add(self, a, b):
return a + b
def _add_user_function(self):
import os
if not os.path.exists('user_instructions.py'):
return
from user_instructions import UserInstructions
self._user_instrucs = UserInstructions(self)
for prop in dir(self._user_instrucs):
if prop.startswith('_'):
continue
prop_type = type(eval("UserInstructions.%s" % prop))
if str(prop_type).find("instancemethod") < 0:
continue
func_str = "def instr_custom_%s(self, *args, **kwargs):\n return self._user_instrucs.%s(*args, **kwargs)\n " % (prop, prop)
exec(func_str)
setattr(Instructions, prop, eval("instr_custom_%s" % prop))
def show(self, arg):
print(arg)
user_instructions.py like below:
class UserInstructions:
def __init__(self, instr):
self.__instr = instr
def print_line(self, args):
print(args)
Upvotes: 2