2

私は現在、Minecraft の 3D ブロック エディターである MCedit python プログラムのフィルターを作成することで、python を学習しています。フィルターは、関数としてプログラム内で実行できる小さなコードです。

MCedit によって提供される関数の 1 つを使用すると、回路図 (ここでは temp という名前) を抽出して変更できます。デモでは、プログラムの作成者が回路図のブロック属性を次の行で変更します。

temp.blocks[temp.blocks == 14] = 52

.blocks 属性は、3 つのレイヤー (x、y、z) で連結されたリストで構成されます。

このコードは、いずれかのリストの値を 14 で 52 に置き換えます。

私はそれを他の値に変更させようとしました:

temp.blocks[temp.blocks == 14 or temp.blocks == 15] = 52

しかし、それは単に機能しません。

他にも方法があることは知っていますが、これは特にシンプルでコンパクトで効率的であるため、どのように機能するかを理解したいと思います。

4

1 に答える 1

2

基礎となるクラスの作成者は、さまざまな Python 式の通常のblocksセマンティクスを置き換えて、ミニ クエリ言語を実装しました。

ほとんどの場合、クラスはおよびフックをblocksオーバーライドします。__setitem____eq__

temp.blocks == 14式はフックによって処理され、構文を介してフックに渡されるある種の特殊なオブジェクトを返し__eq__ます。次に、フックはその特殊化されたオブジェクトを使用して、シーケンス内のどのインデックスを変更するかを決定します。__setitem__[...]__setitem__

==演算子はいずれ__eq__かのオペランドでメソッドを探し、存在する場合はそのメソッドが呼び出され、戻り値 (通常はTrueまたはFalse) がその等価テストの結果として返されます。ただし、__eq__メソッド onは別のtemp.blocksものを返します。また、その「何か」は追加のフック ( や など) を実装__or____and__て、クエリ言語をさらに改良することもできます。

temp.blocks[expr1] = expr2割り当ては に変換されるため、のblocks.__setitem__(expr1, expr2)結果がblocks.__eq__(14)そのメソッドに渡され、「検索クエリ」に基づいて基になるシーケンスが変更されます。

特別なオブジェクトがhookを実装していれば、おそらくうまくいくtemp.blocks[temp.blocks == 14 | temp.blocks == 15] = 52 可能性があります。フックを実装して機能させることもできます。__or____and__&

|and&がサポートされる理由は、 orandandがフックでオーバーライドできないためです (これらの短絡では、フックは両方のオペランドを評価する必要があり、短絡の期待を破ります)。

于 2013-08-06T16:22:45.683 に答える