【问题标题】:How to dispatch methods of a superclass?如何分派超类的方法?
【发布时间】:2023-01-07 15:47:40
【问题描述】:

我想装饰 shapely.geometry.Point 类以从 dendropy.datamodel.basemodel.AnnotationSet 对象实例化它。我选择了 multimethod 包来调度超类的 __init__,因为它将这个方法毫无问题地调度到一个简单的类中:

from multimethod import multimeta

class Example(metaclass=multimeta):
    def __init__(self, *args, **kwargs):
        print("DEFAULT")

    def __init__(self, x: str):
        print("Initialising from a string")

    def __init__(self, x: int):
        print("Initialising from an integer")

但是,它不适用于我的继承情况:

class Point(Point, metaclass=multimeta):
    def __init__(self, annotations: AnnotationSet):
        try:
            super().__init__(
                float(annotations.get_value(LONGITUDE_ALIAS)),
                float(annotations.get_value(LATITUDE_ALIAS)),
            )
        except (TypeError, ValueError):
            raise ValueError(
                f"There is no coordinates in the annotations:\n{annotations}"
            )

它从 AnnotationSet 初始化,但不是从默认参数初始化:

Point(6, 4)

---------------------------------------------------------------------------
DispatchError                             Traceback (most recent call last)
Cell In [461], line 1
----> 1 Point(6, 4)

File ~\anaconda3\envs\bioinfo\lib\site-packages\multimethod\__init__.py:313, in multimethod.__call__(self, *args, **kwargs)
    311 if self.pending:  # check first to avoid function call
    312     self.evaluate()
--> 313 func = self[tuple(func(arg) for func, arg in zip(self.type_checkers, args))]
    314 try:
    315     return func(*args, **kwargs)

File ~\anaconda3\envs\bioinfo\lib\site-packages\multimethod\__init__.py:307, in multimethod.__missing__(self, types)
    305     return self.setdefault(types, *funcs)  # type: ignore
    306 msg = f"{self.__name__}: {len(keys)} methods found"  # type: ignore
--> 307 raise DispatchError(msg, types, keys)

DispatchError: ('__init__: 0 methods found', (<class '__main__.Point'>, <class 'int'>), [])

有没有办法分派超类方法?我对 multimethod 不感兴趣;也许还有什么办法吗?

【问题讨论】:

标签: python python-3.x dispatch multimethod


【解决方案1】:

这是 Coady's answer 征得他们同意后的释义。

要分派超方法,我们需要手动指定它,将其包装到 multimethod 实例中,并使用 register 方法作为第一个新多方法的装饰器。例如,就我而言:

class Point(Point):
    @multimethod(Point.__init__).register
    def __init__(self, annotations: AnnotationSet):
        try:
            super().__init__(
                float(annotations.get_value(LONGITUDE_ALIAS)),
                float(annotations.get_value(LATITUDE_ALIAS)),
            )
        except (TypeError, ValueError):
            raise ValueError(
                f"There is no coordinates in the annotations:
{annotations}"
            )

【讨论】:

    猜你喜欢
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 2020-03-24
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多