What to use in replacement of an interface/protocol in python
我正在做一个象棋游戏,我想做一个标准的棋子接口/协议。python没有这些语言,那么我应该使用什么呢?我读过一些关于工厂的书,但我不知道它们会有什么帮助。事先谢谢!
简而言之,你可能根本不需要担心。由于python使用duck类型(另请参阅wikipedia文章了解更广泛的定义),如果一个对象有正确的方法,它将简单地工作,否则会引发异常。
您可能有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Piece(object): def move(): raise NotImplementedError(optional_error_message) class Queen(Piece): def move(): # Specific implementation for the Queen's movements # Calling Queen().move() will work as intended but class Knight(Piece): pass # Knight().move() will raise a NotImplementedError |
或者,您可以使用isInstance或isubClass显式验证接收到的对象,以确保它具有所有正确的方法,或者它是
您的工厂只需要生成对象的实例,这些对象上有正确的方法。
python 3.7中的新功能:
接口和协议的一些好处是在开发过程中使用内置于IDES中的工具和静态类型分析在运行时之前检测错误的类型提示。通过这种方式,静态分析工具可以告诉您何时检查代码,是否试图访问对象上未定义的任何成员,而不仅仅是在运行时发现。
PEP 544中给出的基本示例说明了如何使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
我通常不在python中使用接口,但是如果必须这样做,您可以使用
我用python编写了一个国际象棋游戏(用tkinter),我的方法是用piece类、queen/knight/etc.类继承piece类、player类、square类和tkinter主循环的主程序类。每个工件都有一个颜色和位置,以及一个方法来帮助为直线移动直到阻塞的工件生成移动集。每个特定的工件子类都包含一个方法来确定它们的移动集。正方形物体包含一块和正方形在板上的位置。
主程序类有一个
我还没有完成版本10,但是您可以在这里获得版本9的源代码和资产。
您还可以查看开源的Shane's Chess信息数据库。我从来没用过,但它看起来很漂亮。
即使Python是动态的,也可以使用鸭子打字,它仍然可以实现Java和C语言调用的"接口"。这是通过声明抽象基类来实现的。https://docs.python.org/2/library/abc.html或https://docs.python.org/3.4/library/abc.html
定义ABC时,将所有类似接口的方法放在其中,并在它们的主体中包含