函数内部函数最好的方法?

时间:2013-10-15 14:54:31

标签: python function class events

我在下面有以下代码。当事件被触发时,我想在handleResponseEvent()内执行额外的C1类方法。通过实验我发现,如果我在handleResponseEvent()内定义main(),它就能做我想要的。我想知道是否还有其他方法可以做同样的事情,如果在main()中定义事件处理函数是最好的方法。

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
    ....

3 个答案:

答案 0 :(得分:2)

在使用外部函数的局部变量的另一个函数内部定义函数非常有意义,特别是当您将内部函数本身传递给代码的另一部分时,就像使用事件订阅一样。

然而,看看你的代码,你需要的对象和事件之间似乎已经存在直接关系。我看到C1.method2.RequestEvent,因此看起来RequestEvent很容易引用C1。如果是这种情况,那么它可以将其传递给处理程序,其中处理程序看起来像这样:

def handleResponseEvent(request, response, dnp):

其中dnp是事件引用的DNPClass实例(C1)。 requestresponse也可能已经引用DNPClass,因此您不需要额外的参数。

这将允许您使用相同的处理程序进行订阅,而不管实例如何。例如:

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()
    ...

如果这不起作用,并且编辑DNPClass代码以使其工作是不可行的,那么我至少会将其限制为接受该实例的单个函数,因此您不需要每次都定义一个新的内部函数。像这样:

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)
    ...

答案 1 :(得分:0)

如果handleResponseEvent未在其他地方使用,则可能会在main中。这可能比使C1全局更好。您也可以将C1作为参数传递(您必须更改handleResponseEvent的签名并修改method2.RequestEvent)。

答案 2 :(得分:0)

我采用这种方法的唯一问题是我不会在main函数中执行此操作,否则它完全有效。

这就是我所说的功能性方法; OOP方法会使handleResponseEvent成为类DPNClass的方法,因此代码看起来像

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
        ....

这当然只有在您DPNClass课程属于您的课程并且您可以修改它时才有可能;否则你可以创建自己的类并在那里包装C1。