@zikzak: Man kann sich ja den Quelltext zum Buch herunterladen. Und er hat in der finalen Schachversion mitnichten alles durch eine Klasse ersetzt, sondern erzeugt für *jede* Spielfigur, also Art und Farbe, dynamisch eine Klasse:
Code: Alles auswählen
def create_piece(kind, color):
color = "White" if color == WHITE else "Black"
name = {DRAUGHT: "Draught", PAWN: "ChessPawn", ROOK: "ChessRook",
KNIGHT: "ChessKnight", BISHOP: "ChessBishop",
KING: "ChessKing", QUEEN: "ChessQueen"}[kind]
return globals()[color + name]()
class Piece(str):
__slots__ = ()
for code in itertools.chain((0x26C0, 0x26C2), range(0x2654, 0x2660)):
char = chr(code)
name = unicodedata.name(char).title().replace(" ", "")
if name.endswith("sMan"):
name = name[:-4]
new = (lambda char: lambda Class: Piece.__new__(Class, char))(char)
new.__name__ = "__new__"
Class = type(name, (Piece,), dict(__slots__=(), __new__=new))
globals()[name] = Class
Ja, da muss man dann in der Tat sehr genau hinschauen was passiert. Aber nur weil das so verflucht überkompliziert und undurchsichtig gelöst ist. Diese Marotte überall ``__slots__ = ()`` zu verwenden verstehe ich auch nicht. Also mir ist schon klar was das bewirkt, aber nicht warum man das hier haben möchte‽ Das ist IMHO ein Paradebeispiel von „premature optimization”.
Warum `Piece`? Aber von so etwas scheint er auch Fan zu sein. Das Wortzählbeispiel enthält eine abstrakte Klasse die nur zwei *statische* Methoden enthält die jeweils `NotImplemented` auslösen. *Warum* nur?