我正在构建一种用Python编写CraftBukkit(Minecraft modded服务器软件)脚本的方法。
我通过使用Jython加载Python脚本,然后为事件添加装饰器等来完成此操作。
我目前正在实现事件装饰器,但是我遇到了一个问题:没有参数的装饰器工作正常,但是一旦我添加一个参数,就会开始抱怨没有足够的参数。
这有效:
@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
答案 0 :(得分:0)
这与Jython无关。等效的纯Python代码显示了实际问题(为了简单起见,我省略了类或名称空间script
):
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