简体   繁体   English

使用isinstance的Python多方法

[英]Python multimethods using isinstance

In this article Guido van Rossum says that this kind of multimethod implementation in Python: Guido van Rossum在本文中说过,这种在Python中的多方法实现:

def foo(a, b):
    if isinstance(a, int) and isinstance(b, int):
        ...code for two ints...
    elif isinstance(a, float) and isinstance(b, float):
        ...code for two floats...
    elif isinstance(a, str) and isinstance(b, str):
        ...code for two strings...
    else:
        raise TypeError("unsupported argument types (%s, %s)" % (type(a), type(b)))

is "tedious" and "not very OO". 是“乏味的”和“不是很OO”。 He then goes into a description of how decorators may be used to implement multimethods which I would think would be inaccessible to those without a rather deep knowledge of Python. 然后,他介绍了如何使用装饰器来实现多重方法,我认为这些方法如果没有Python的较深知识,那将是无法访问的。

My question: I need to write a multimethod, what is actually "not OO" about the code above? 我的问题:我需要编写一个多方法,上面的代码实际上是什么“不是OO”?

UPDATE : In light of Thomas Orozco's answer, I now realise I don't actually "need" to write a multimethod at all. 更新 :根据Thomas Orozco的回答,我现在意识到我实际上根本不需要“编写”多种方法。

Rather than inspecting the types of the objects that are being passed to your method, you would make it so that the objects implement the logic themselves. 与其检查传递给您方法的对象的类型,不如检查对象的类型,以使对象自己实现逻辑。

Lets take an example: the len function. 让我们举个例子: len函数。

A native implementation would be: 本机实现为:

def len(x):
    if type(x) == str:
        # compute the length of a string
    elif type(x) == list:
        # compute the length of a list
    else:
        #

But this has a few caveats 但这有一些警告

  • You couldn't support len in your own objects without re-implementing len 如果不重新实现len就无法在自己的对象中支持len
  • It's a huge, unreadable, mess 这是一个巨大的,难以理解的混乱

And, most importantly, the OO-part about it, it means that your implementation of str is scattered across your codebase: the code for computing its length is here, the code for slicing it is somewhere else... 而且,最重要的是,它的面向对象部分意味着它的str实现分散在代码库中:用于计算其长度的代码在这里,用于对其进行切片的代码在其他地方...


Instead, a much saner design is what's used in Python: 取而代之的是,Python中使用的设计更为精巧:

def len(x):
    return x.__len__()

It's then up to each object to implement the __len__ method itself. 然后由每个对象自己实现__len__方法。 The len function just asks the object for its length. len函数只是询问对象的长度。

To a certain extent, you can consider this a "Strategy Pattern" 在某种程度上,您可以将其视为“策略模式”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM