1

Python を使用して CraftBukkit (Minecraft modded サーバー ソフトウェア) をスクリプト化する方法を構築しています。

これを行うには、Python スクリプトを Jython でロードし、イベントのデコレーターなどを用意します。

現在、イベント デコレータを実装していますが、問題があります。引数のないデコレータは正常に動作しますが、引数を追加するとすぐに、十分な引数がないという不平を言い始めます。

これは機能します:

@script.event
def test(event):
    print "hi" # Works

public void event(PyFunction func) {
    return func;
}

これはしません:

@script.event("player.PlayerMoveEvent", "normal")
def test(event):
    print "player moved!" # TypeError: event(): 1st arg can't be coerced to org.python.core.PyFunction

public void event(PyFunction func, PyString eventType, PyString priority) {
    // Do all kinds of crap
    return func;
}

これが私のJavaコードです: http://pastebin.com/GsULYdJr

4

1 に答える 1

0

これは Jython とは関係ありません。script同等の純粋な Python コードは、実際の問題を示しています (わかりやすくするために、クラスまたは名前空間を省略しています)。

def event(func, event_type, priority):
    # ...
    return func

@event("player.PlayerMoveEvent", "normal")
def test(event):
    print "player moved"

エラーは

Traceback (most recent call last):
  ...
TypeError: event() missing 1 required positional argument: priority

デコレータの誤解が原因です。装飾された関数定義がこのように実行されることを期待しています

def test(event):
    print "player moved"

test = event(test, "player.PlayerMoveEvent", "normal")

しかし、それは次のように実行されます:

__decorator = event("player.PlayerMoveEvent", "normal")

def test(event):
    print "player moved"

test = __decorator(test)

の後ろの部分@は単独で評価され、その結果は関数testを引数として呼び出されます。Python での通常の修正はクロージャを使用することですが、Java ではおそらく面倒です。デコレータの一部を Python で記述し、Java コードを現在のままにしておくのがおそらく最も簡単です。

def script(event_type, priority):
    def decorate(func):
        return script.event(func, event_type, priority)
    return decorate
于 2013-10-13T14:23:16.710 に答える