cjbust
cjbust

Reputation: 123

Function inside a function best approach?

I have the following code below. I would like to execute additional C1 Class methods inside handleResponseEvent() when the event is fired. Experimenting I found that if I define handleResponseEvent() inside main() it does what I want. I was wondering if there are other ways of doing the same thing and if defining the event handler function inside main() was the best approach.

def main():
    C1 = DNPClass()
    C1.method1(arg1, arg2, arg3, arg4, arg5)

    # subscribing to event
    C1.method2.RequestEvent += handleResponseEvent
    ...

def handleResponseEvent( request, response):
    #code to execute when event handler is called
    #code references additional method from C1 instance
    ....

Upvotes: 0

Views: 91

Answers (3)

nmclean
nmclean

Reputation: 7724

Defining a function inside of another function where you are using the local variables of the outer function makes perfect sense, particularly when you are passing out the inner function itself to another part of code, like you do with event subscription.

However, looking at your code, there already seems to be a direct relationship between the object you need and the event. I see C1.method2.RequestEvent, so it looks like RequestEvent could easily have a reference to C1. If that is the case, then it could pass that into the handler, where the handler looks something like this:

def handleResponseEvent(request, response, dnp):

where dnp is the DNPClass instance referenced by the event (C1). It's also possible that request or response already refer back to the DNPClass, so you wouldn't need the extra argument.

This would allow you to subscribe using the same handler regardless of the instance. For example:

def main():
    C1 = DNPClass()
    C1.method1(arg1, arg2, arg3, arg4, arg5)

    # subscribing to event
    C1.method2.RequestEvent += handleResponseEvent  # will call C1.method3

    C2 = DNPClass()

    C2.method2.RequestEvent += handleResponseEvent  # will call C2.method3


def handleResponseEvent(request, response):
    #code to execute when event handler is called
    #code references additional method from current DNPClass instance
    request.dnp.method3()
    ...

If this doesn't work, and it's not feasible to edit the DNPClass code to make it work, then I would at least confine this to a single function that accepts the instance so you don't need to define a new inner function each time. Something like this:

def subscribe_handleResponseEvent(dnp):
    def handleResponseEvent(request, response):
        #code to execute when event handler is called
        #code references additional method from dnp instance
        dnp.method3()
        ...

    dnp.method2.RequestEvent += handleResponseEvent


def main():
    C1 = DNPClass()
    C1.method1(arg1, arg2, arg3, arg4, arg5)

    # subscribing to event
    subscribe_handleResponseEvent(C1)
    ...

Upvotes: 2

volferine
volferine

Reputation: 372

The only issue I would take with this approach is that I wouldn't do that in the main function, otherwise it is perfectly valid.

This is what I would call a functional approach; an OOP approach would make handleResponseEvent a method of the class DPNClass, so that the code would look like

def main():
    C1 = DNPClass()
    C1.method1(arg1, arg2, arg3, arg4, arg5)

    # subscribing to event
    C1.method2.RequestEvent += C1.handleResponseEvent
    ...

class DPNClass(...):
    ...
    def handleResponseEvent(self, request, response):
        #code to execute when event handler is called
        #code references additional method from self instance
        ....

This is of course possible only if you the class DPNClass is yours and you can modify it; otherwise you can create your own class and wrap C1 there.

Upvotes: 0

jpkotta
jpkotta

Reputation: 9417

If handleResponseEvent is not used anywhere else, it might as well be in main. It's probably better than making C1 global. You could also pass C1 as a parameter (you'd have to change the signature of handleResponseEvent and modify method2.RequestEvent).

Upvotes: 0

Related Questions