Pythonic在类中使用Python3的functools.singledispatch的方法?

时间:2013-11-29 03:28:13

标签: python python-3.x

我正在转换到Python3,并且一直在探索stdlib的一些功能。 functools.singledispatch引起了我的注意,我一直在玩它。但是,在我尝试在课堂上使用它时,我遇到了一些问题。

它似乎不适用于在类中注册的函数,您可以通过直接调用fun.dispatch(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)

4 个答案:

答案 0 :(得分:2)

以下内容应该有效。不管它是不是最好的解决方案,我不知道。

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

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

...
...

答案 1 :(得分:1)

我找到了答案 - 你不

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

从我在上述网址找到的帖子中引用我认为已经解释过了 - 简短的回答是通用功能'用于无状态算法。我没有意识到这个定义。

  

正确。 OO和泛型函数是不同的开发范例,   混合它们有局限性。通用功能适用于   无状态算法,期望接收所有必需的输入   通过他们的论点。相比之下,类和实例方法   期望在很多方面隐含地接受一些国家   已经是泛型函数。

     

因此,这实际上是一种伪装双重派遣的请求:你想要的   首先在类或实例上发送(通过方法发送)   然后然后在第二个参数上发送(通过泛型函数)   调度)。

     

双重调度比单一调度更难   " functools.singledispatch"是不是也不应该支持它(它在   名字)。正如PJE所说,你可以使用singledispatch   staticmethods,因为它消除了双重调度行为   删除基于类和实例的调度步骤。你也可以   将已绑定的类和实例方法注册为实现   对于通用函数,因为它也解决了a中的双重调度问题   方式意味着单一调度实施甚至不需要   要知道它正在发生。

答案 2 :(得分:1)

这是我的解决方案,可以在任何Python(3.8或更低版本)上工作

class CustomPath(path: android.graphics.Path, paint: android.graphics.Paint){
    private var path: Path
    private var paint: Paint

    init {
        this.paint = paint
        this.path = path

    }

    fun setPath(path:Path){
        this.path = path
    }
    fun getPath(): Path {
        return this.path
    }

    fun setPaint(paint:Paint){
        this.path = path
    }
    fun getPaint(): Paint {
        return this.paint
    }

}```

答案 3 :(得分:0)

https://docs.python.org/3/library/functools.html#functools.singledispatchmethod

从python 3.8开始,有一个stdlib函数用于方法分派