用什么代替python中的接口/协议

Big*_*Mac 11 python protocols interface

我正在制作一个国际象棋游戏,并希望制作一个标准的接口/协议.Python没有语言中的那些,所以我应该使用什么?我读了一些关于工厂的内容,但我不确定他们会如何提供帮助.提前致谢!

Vla*_*lad 8

简而言之,您可能根本不需要担心它.由于Python使用duck typing - 请参阅Wikipedia文章以获得更广泛的定义 - 如果对象具有正确的方法,它将简单地工作,否则将引发异常.

你可能有一个Piece基类,抛出一些方法NotImplementedError来表明它们需要重新实现:

class Piece(object):

    def move(<args>):
        raise NotImplementedError(optional_error_message) 

class Queen(Piece):

    def move(<args>):
        # Specific implementation for the Queen's movements

# Calling Queen().move(<args>) will work as intended but 

class Knight(Piece):
    pass

# Knight().move() will raise a NotImplementedError
Run Code Online (Sandbox Code Playgroud)

或者,您可以显式验证您收到的对象,以确保它具有所有正确的方法,或者它是Piece使用isinstanceisubclass的子类.请注意,某些人可能不会将检查类型视为"Pythonic",并且使用该NotImplementedError方法或abc模块 - 如本非常好的答案所述 - 可能更为可取.

您的工厂只需要生成具有正确方法的对象实例.


goo*_*der 6

Python 3.7的新功能:

接口和协议的一些好处是,在开发过程中使用IDE内置的工具进行类型提示,以及在运行时之前检测错误的静态类型分析。这样,静态分析工具可以在您检查代码时告诉您是否要访问未在对象上定义的任何成员,而不仅仅是在运行时查找。

typing.Protocol类将被添加到Python 3.7作为用于机制“结构亚型”。其背后的功能是它可以用作隐式基类。也就是说,Protocol出于静态类型分析的目的,具有与定义的成员匹配的成员的任何类都被视为其子类。

PEP 544中给出的基本示例说明了如何使用它。

from typing import Protocol

class SupportsClose(Protocol):
    def close(self) -> None:
        # ...

class Resource:
    # ...
    def close(self) -> None:
        self.file.close()
        self.lock.release()

def close_all(things: Iterable[SupportsClose]) -> None:
    for thing in things:
        thing.close()

file = open('foo.txt')
resource = Resource()
close_all([file, resource])  # OK!
close_all([1])     # Error: 'int' has no 'close' method
Run Code Online (Sandbox Code Playgroud)

  • 是的,可以显式声明一个实现,[如后面的 PEP 544 所示](https://www.python.org/dev/peps/pep-0544/#explicitly-declaring-implementation)。 (4认同)
  • 好吧,PEP 544 给出的示例展示了如何使用“typing.Protocol”来支持静态类型分析和类型提示。为此,类是否显式或隐式实现“协议”是无关紧要的。实际上我不喜欢显式继承“Protocol”,因为这会破坏它的用处。如果子类对协议上定义的方法的显式实现作为重构的一部分被故意删除,那么它的使用者仍然可以调用此方法,而不会被静态类型提示工具警告该方法不再存在。 (2认同)
  • 是的,它很棒:定义一个协议,并实现它,并以“该接口可能被其他人错误地删除”为借口,让你很难弄清楚你刚刚做了什么。你的例子和答案与OP的问题无关,因为你自己就是消费者。 (2认同)