python - python中的动态调度和继承

标签 python dynamic-dispatch

我正在尝试修改 Guido 的多方法(动态调度代码):

http://www.artima.com/weblogs/viewpost.jsp?thread=101605

处理继承和可能乱序的参数。

例如(继承问题)

class A(object):
  pass

class B(A):
  pass

@multimethod(A,A)
def foo(arg1,arg2):
  print 'works'


foo(A(),A()) #works

foo(A(),B()) #fails

有没有比迭代检查每个项目的 super() 直到找到一个更好的方法?

例如(参数排序问题) 我是从碰撞检测的角度考虑这个问题的。

例如

foo(Car(),Truck()) and
foo(Truck(), Car()) and

应该都触发

foo(Car,Truck) # Note: @multimethod(Truck,Car) will throw an exception if @multimethod(Car,Truck) was registered first?

我正在专门寻找“优雅”的解决方案。我知道我可以强行通过所有的可能性,但我正在努力避免这种情况。我只是想在坐下来敲定解决方案之前获得一些意见/想法。

谢谢

最佳答案

关于继承问题:这可以通过对 MultiMethod 进行轻微更改来完成。 (遍历 self.typemap 并使用 issubclass 检查):

registry = {}

class MultiMethod(object):
    def __init__(self, name):
        self.name = name
        self.typemap = {}
    def __call__(self, *args):
        types = tuple(arg.__class__ for arg in args) # a generator expression!
        for typemap_types in self.typemap:
            if all(issubclass(arg_type,known_type)
                   for arg_type,known_type in zip(types,typemap_types)):
                function = self.typemap.get(typemap_types)
                return function(*args)
        raise TypeError("no match")
    def register(self, types, function):
        if types in self.typemap:
            raise TypeError("duplicate registration")
        self.typemap[types] = function

def multimethod(*types):
    def register(function):
        name = function.__name__
        mm = registry.get(name)
        if mm is None:
            mm = registry[name] = MultiMethod(name)
        mm.register(types, function)
        return mm
    return register

class A(object):
  pass

class B(A):
    pass

class C(object):
    pass

@multimethod(A,A)
def foo(arg1,arg2):
  print 'works'


foo(A(),A()) #works

foo(A(),B()) #works

foo(C(),B()) #raises TypeError

注意 self.typemap 是一个字典,而且字典是无序的。所以如果你使用@multimethod 来注册两个函数,一个的类型是另一个的子类,那么 foo 的行为可能是未定义的。也就是说,结果将取决于哪个 typemap_types 在循环 for typemap_types in self.typemap 中首先出现。

关于python - python中的动态调度和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4641289/

相关文章:

python : several cumprods per column

python - float64 到 float32 Cython 错误

python - on_delete 对 Django 模型有什么作用?

c++ - 替代虚拟模板

python - Python中的微分方程

python - Windows 上 PyCharm 中 numpy 的安装

ios - Swift 函数中的动态修饰符

java - 在 Java 中神奇地调用方法

monkeypatching - 如何猴子修补泛型类型标记函数表

java - 从对象引用访问父类(super class)方法(新手)