2

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.

4
  • 1
    Have you tried inheritance? Commented Aug 22, 2018 at 2:20
  • The processor code imports only the class Instructions. If the user functions are an inherited class from Instructions, I would still need to load this new class into the instructions file. Commented Aug 22, 2018 at 2:28
  • You can add methods to an existing class or class instance, but it gets ugly. Check Adding a Method to an Existing Object Instance Commented Aug 22, 2018 at 2:38
  • Can you think of easier ways other than adding new methods to the Instruction class? Commented Aug 22, 2018 at 2:42

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

9 Comments

I can't change the processor code, so this does not solve the problem.
I can change the instructions code, but it still has to be able to be executed by the processor.
Thus you put print_line method in class Instructions, that will take effect.
print_line is just one function that the user might create. The user should be able to create any function he wants in another file and it should be added to the other instructions of the class Instructions.
@klaus Just... define the function and snap it to the class like you're changing one of it's attributes. It's as straightforward as it gets.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.