使my_average(a,b)与定义了f_add和d_div的任何a和b一起使用。以及内置

使my_average(a,b)与定义了f_add和d_div的任何a和b一起使用。以及内置,第1张

使my_average(a,b)与定义了f_add和d_div的任何a和b一起使用。以及内置

如果您已经

my_average(a, b)
按照
add
div
功能实现了,例如:

def my_average(a, b):    return div(add(a, b), 2)

然后为不同的类型提供不同的实现,可以使用

functools.singledispatch

import functools@singledispatchdef div(x, y:int): # default implementation    raise NotImplementedError('for type: {}'.format(type(x)))@div.register(Divisible) # anything with __truediv__ methoddef _(x, y):    return x / y@singledispatchdef add(a, b):     raise NotImplementedError('for type: {}'.format(type(a)))@add.register(Addable) # anything with __add__ methoddef _(a, b):    return a + b

其中

Addable
Divisable
可以定义为:

from abc import ABCmeta, abstractmethodclass Divisible(metaclass=ABCmeta):    """Anything with __truediv__ method."""    __slots__ = ()    __hash__ = None # disable default hashing    @abstractmethod    def __truediv__(self, other):        """Return self / other."""    @classmethod    def __subclasshook__(cls, C):        if cls is Divisible: if any("__truediv__" in B.__dict__ for B in C.__mro__):     return True        return NotImplementedclass Addable(metaclass=ABCmeta):    """Anything with __add__ method."""    __slots__ = ()    __hash__ = None # disable default hashing    @abstractmethod    def __add__(self, other):        """Return self + other."""    @classmethod    def __subclasshook__(cls, C):        if cls is Addable: if any("__add__" in B.__dict__ for B in C.__mro__):     return True        return NotImplemented
>>> isinstance(1, Addable) # has __add__ methodTrue>>> isinstance(1, Divisible) # has __truediv__ methodTrue>>> my_average(1, 2)1.5>>> class A:...   def __radd__(self, other):...     return D(other + 1)...>>> isinstance(A(), Addable)False>>> _ = Addable.register(A) # register explicitly>>> isinstance(A(), Addable)True>>> class D:...   def __init__(self, number):...     self.number = number...   def __truediv__(self, other): ...     return self.number / other...>>> isinstance(D(1), Divisible) # via issubclass hookTrue>>> my_average(1, A())1.0>>> my_average(A(), 1) # no A.__div__Traceback (most recent call last):...TypeError: unsupported operand type(s) for +: 'A' and 'int'

内置数字,例如

int
define
__add__
__truediv__
method,因此它们自动得到支持。如类
A
所示,即使它们没有定义特定的方法,也可以使用类,例如,如果仍然可以在给定的实现中使用它们,则可以通过显式
__add__
调用
.register
方法。

如有必要,使用

add.register
div.register
定义其他类型的实现,例如:

@div.register(str)def _(x, y):    return x % y

之后:

>>> my_average("%s", "b") # -> `("%s" + "b") % 2`'2b'


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5667602.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存