【问题标题】:Passing varargs to Java from Python using Py4j使用 Py4j 从 Python 将 varargs 传递给 Java
【发布时间】:2017-03-17 16:28:47
【问题描述】:

我正在尝试将可变参数从 python 传递给 Java 代码。

Java 代码: LogDebugCmd.java

public class LogDebugCmd implements Command {
  private Class clazz;
  private String format;
  private Object[] args;

  public LogDebugCmd() {}
  public void setLog(String format, Object... args) {
    this.format = format;
    this.args = args.clone();
    clazz = getClass();
  }

  @Override
  public void execute() {
    VLog.getLog(clazz).debug(format, args);
  }

CommandEntryPoint.java

public class CommandEntryPoint {
  private LogDebugCmd logDebugCmd;

  public CommandEntryPoint() {
    logDebugCmd = new LogDebugCmd();

  public LogDebugCmd getLogDebugCmd(String str, Object... args) {
    setLog(str, args);
    return logDebugCmd;
  }
  public static void main(String args[]) {
    GatewayServer gatewayServer = new GatewayServer(new CommandEntryPoint());
    gatewayServer.start();
    System.out.println("Gateway Server Started");
  }

Python 代码 测试.py:

from py4j.java_gateway import JavaGateway
gateway = JavaGateway()
logDebugCmd = gateway.entry_point.getLogDebugCmd("Step 01 - Test initiated.")
logDebugCmd..execute()

错误:

Traceback (most recent call last):
  File "C:/Python27/Lib/site-packages/py4j-0.10.3-py2.7.egg/py4j/sampleTLStest.py", line 4, in <module>
    logDebugCmd = gateway.entry_point.getLogDebugCmd("Step 01 - Test initiated.")
  File "C:\Python27\lib\site-packages\py4j-0.10.3-py2.7.egg\py4j\java_gateway.py", line 1133, in __call__
    answer, self.gateway_client, self.target_id, self.name)
  File "C:\Python27\lib\site-packages\py4j-0.10.3-py2.7.egg\py4j\protocol.py", line 323, in get_return_value
    format(target_id, ".", name, value))
***Py4JError: An error occurred while calling t.getLogDebugCmd. 
Trace:
py4j.Py4JException: Method getLogDebugCmd([class java.lang.String]) does not exist at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318)
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:326)
at py4j.Gateway.invoke(Gateway.java:272)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:214)
at java.lang.Thread.run(Thread.java:745)***

有没有办法将可变参数传递给 Java ?我正在尝试将 String 作为第二个参数传递给 getLogDebugCmd() ,这也会出错。

【问题讨论】:

    标签: java python variadic-functions py4j


    【解决方案1】:

    可变参数实际上表示为一个数组,因此您可以这样做:

    # Pass a None if you have no varargs
    logDebugCmd = gateway.entry_point.getLogDebugCmd("Step 01 - Test initiated.", None)
    
    # Create an array of objects
    object_class = gateway.jvm.Object
    object_array = gateway.new_array(object_class, 2)
    object_array[0] = "foo"
    object_array[1] = "bar"
    logDebugCmd = gateway.entry_point.getLogDebugCmd("Step 01 - Test initiated.", object_array)
    

    有一个pull request 用于改进 Py4J 中对可变参数的支持,但它存在一些编译问题,因此尚未合并。

    【讨论】:

    • 感谢您的快速回复,@Barthelemy!这有帮助。
    • 仅通过传递“无”进行更正 -> 将“无”转换为“对象”类型,然后将其传递给对象...参数。作为一种让 Java 清楚的方式,我们传递的是 Null Object 而不是 null 来代替 Object 数组。后者将导致 NullPointerException。参考:link。例如:object_array[0] = None logDebugCmd = gateway.entry_point.getLogDebugCmd("Step 01 - Test initiated.", object_array)
    • 其实这取决于被调用的代码:如果它检查args是否为null,你不会得到NullPointerException。现在想想,你最好创建一个空数组:object_array = gateway.new_array(object_class, 0)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 2012-04-09
    • 2013-01-05
    • 1970-01-01
    • 2017-02-14
    • 2014-11-11
    • 2014-08-22
    相关资源
    最近更新 更多