Equivalent of Ruby's prepend in Python?

Question:

I’m working on a software and I have to convert it from Ruby to Python.
It’s working great, but there is a feature I need to develop that requires me to use an equivalent of the prepend method in Ruby in a pythonic way.

Does this thing exists in Python? How can I implement it?

Let me explain it with some code:

I’ve got one library, called LibA.

In there I have a class JobHandler:

class JobHandler:
    
    def __init__(self):
        print('JobHandler init constructor')

    def process_message(self, message):
        # Do things with message
        # ...
        # Finally send the message
        send(message)

I’ve got an other library, called LibB, with a class JobHandling:

class JobHandling:
    
    def __init__(self):
        print('JobHandling init constructor')

    def process_message(self, message):
        # Do things with message
        # ...

        # -> Here in Ruby I can call method super
        ## super

These are 2 differents libraries, don’t ask why, they just don’t do the same.

Now, I’m developing a program, that uses LibA & LibB (those libs are installed into my Pipfile / requirements.txt).

There I’ve got a new class that looks like this:

from LibA.handlers.JobHandler import JobHandler
from LibB.handlers.JobHandling import JobHandling

class ProgramJobHandler(JobHandler):

    # -> Here in Ruby i can use `prepend JobHandling`
    ## prepend JobHandling
    # So everytime my ProgramJobHandler.process_message is called (inherited from JobHandler),
    # it's JobHandling.process_message who is called first

    def __init__(self):
        print('My program job handler constructor')

As you can see, the call to ProgramJobHandler.process_message will first call JobHandling.process_message that uses super keyword to look up and call the JobHandler.process_message method.

Is there a way to do that in Python, some sort of equivalence of preprend ?
I can’t use LibA into my LibB, I can only use both in the same program.

Thanks for you help.

Asked By: Bloodbee

||

Answers:

I don’t think there is anything directly equivalent to prepend in Python, but in your use case you don’t actually need prepend at all since prepend is only needed when the class you’re prepending with (JobHandling) needs to be even lower than the class you’re prepending to (ProgramJobHandler) in the inheritance chain, so that when there is a method name conflict, the method of the former can be called before that of the latter.

But since your own ProgramJobHandler class doesn’t define process_message itself and relies on its parent class JobHandler to define it, you can simply make ProgramJobHandler inherit both JobHandling and JobHandler (in that order) so that JobHandling.process_message gets called when ProgramJobHandler.process_message is called, and JobHandling.process_message can then call super().process_message to cooperatively pass the baton to the process_message method further up the inheritance chain to JobHandler.process_message:

class JobHandler:
    def process_message(self, message):
        print('JobHandler', message)

class JobHandling:
    def process_message(self, message):
        print('JobHandling', message)
        super().process_message(message)

class ProgramJobHandler(JobHandling, JobHandler):
    pass

ProgramJobHandler().process_message('hi')

This outputs:

JobHandling hi
JobHandler hi

Demo: https://replit.com/@blhsing/DependableTremendousRam

Answered By: blhsing
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.