0

Many languages support ad-hoc polymorphism (a.k.a. function overloading) out of the box. However, it seems that Python opted out of it. Still, I can imagine there might be a trick or a library that is able to pull it off in Python. Does anyone know of such a tool?

For example, in Haskell one might use this to generate test data for different types:

-- In some testing library:
class Randomizable a where
   genRandom :: a

-- Overload for different types
instance Randomizable String where genRandom = ...
instance Randomizable Int    where genRandom = ...
instance Randomizable Bool   where genRandom = ...


-- In some client project, we might have a custom type:
instance Randomizable VeryCustomType where genRandom = ...

The beauty of this is that I can extend genRandom for my own custom types without touching the testing library.

How would you achieve something like this in Python?

4

4 回答 4

3

Python 不是一种强类型语言,所以如果你有 Randomizable 的实例或其他具有相同方法的类的实例,这并不重要。

获得所需外观的一种方法可能是:

types_ = {}
def registerType ( dtype , cls ) :
    types_[dtype] = cls
def RandomizableT ( dtype ) :
    return types_[dtype]

首先,是的,我确实用大写字母定义了一个函数,但它的作用更像是一个类。例如:

registerType ( int , TheLibrary.Randomizable )
registerType ( str , MyLibrary.MyStringRandomizable )

然后,稍后:

type = ... # get whatever type you want to randomize
randomizer = RandomizableT(type) ()
print randomizer.getRandom()
于 2015-10-16T18:50:57.007 回答
2

Python 函数不能基于静态编译时类型自动特化。因此,它的结果只能取决于在运行时收到的参数和全局(或本地)环境,除非函数本身可以就地修改并且可以携带一些状态。

genRandom除了输入信息之外,您的通用函数不接受任何参数。因此在 Python 中,它至少应该接收类型作为参数。由于无法修改内置类,因此此类类的通用函数(实例)实现应该以某种方式通过全局环境提供或包含在函数本身中。

我发现从 Python 3.4 开始,就有了@functools.singledispatch装饰器。但是,它仅适用于接收类型实例(对象)作为第一个参数的函数,因此不清楚如何在您的示例中应用它。我也对其理由感到有些困惑:

此外,目前 Python 代码的一种常见反模式是检查接收到的参数的类型,以便决定如何处理这些对象。

我知道反模式是一种被认为不受欢迎的模式的行话(并且根本不意味着没有模式)。因此,基本原理声称检查参数类型是不可取的,并且该声明用于证明引入一种工具的合理性,该工具将简化......对参数类型的调度。(顺便提一下,请注意,根据PEP 20,“显式优于隐式。”)

然而, PEP 443“单调度通用函数”“替代方法”部分似乎值得一读。有几个可能的解决方案的参考资料,包括Guido van Rossum 于 2005 年撰写的“Python 中的五分钟多方法”一文。

于 2019-02-09T12:51:02.633 回答
0

另一个版本的多态性

from module import aName

如果两个模块使用相同的接口,您可以导入其中一个并在代码中使用它。一个例子是from xml.etree.ElementTree import XMLParser

于 2015-10-16T18:54:16.377 回答
0

这算临时多态性吗?

class A:
    def __init__(self):
        pass

    def aFunc(self):
        print "In A"

class B:
    def __init__(self):
        pass

    def aFunc(self):
        print "In B"

f = A()
f.aFunc()
f = B()
f.aFunc()

输出

In A
In B
于 2015-10-16T18:49:06.217 回答