Python使用Python的方式functools.singledispatch在课堂上?

2024-10-03 21:27:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在过渡到Python3,并一直在探索stdlib的一些功能。functools.singledispatch引起了我的注意,我一直在玩它。然而,在我尝试在课堂上使用它的时候,我遇到了一些问题。在

它似乎不适用于类内注册的函数,您可以通过直接调用乐趣。快感(type(arg))(argname=arg),我想知道是否有更好的方法来实现它。在

我尝试在注册的上面和下面使用@classmethod和@staticmethod作为装饰器,但是没用。在

下面是一个人为的例子,它注册处理程序,以便在创建类时转换输入参数,以确保它始终是一个列表。在

from functools import singledispatch

class UrlDispatcher(object):

    @singledispatch
    def url_input(self, input):
        print('input wasn\'t dispatched', input)

    @url_input.register(str)
    def _(self, input):
        print('input is a str', input)
        self.input = [input]

    @url_input.register(list)
    def _(self, input):
        print('input is a list', input)
        self.input = input

    def __init__(self, arg):

        # Works, albeit clunkily
        self.url_input.dispatch(type(arg))(self,input=arg)

        # Always uses the base dispatcher
        self.url_input(input=arg)

a = "http://www.cnn.com"
b = ["http://www.google.com", "http://www.slashdot.org"]

s1 = UrlDispatcher(a)
s2 = UrlDispatcher(b)

Tags: selfregisterhttpurlinputisdefwww
2条回答

我找到了答案-你不知道。在

http://code.activestate.com/lists/python-dev/122554/

引用我在上面的URL上找到的一篇文章,我想已经解释过了——简短的回答是“泛型函数”是用于无状态算法的。我不知道这个定义。在

Correct. OO and generic functions are different development paradigms, and there are limitations on mixing them. Generic functions are for stateless algorithms, which expect to receive all required input through their arguments. By contrast, class and instance methods expect to receive some state implicitly - in many respects, they already are generic functions.

Thus, this is really a request for dual dispatch in disguise: you want to first dispatch on the class or instance (through method dispatch) and then dispatch on the second argument (through generic function dispatch).

Dual dispatch is much harder than single dispatch and "functools.singledispatch" does not and should not support it (it's in the name). As PJE noted, you can use singledispatch with staticmethods, as that eliminates the dual dispatch behaviour by removing the class and instance based dispatch step. You can also register already bound class and instance methods as implementations for a generic function, as that also resolves the dual dispatch in a way that means the single dispatch implementation doesn't even need to be aware it is happening.

下面的方法应该行得通。不管这是不是最好的解决办法,我不知道。在

class Foo:
    def method(self, arg):
        _method(arg, self)

@functools.singledispatch
def _method(arg, self):
    ...

...
...

相关问题 更多 >