【问题标题】:call python script function from scala从scala调用python脚本函数
【发布时间】:2020-05-18 20:02:13
【问题描述】:

尝试从 scala 调用 python 函数失败并出现以下错误。但是当直接从命令行调用相同的命令时工作正常。

请在下面找到简化代码 sn-ps :-

greeting.py

import logging
import os


def greet(arg):
    print("hey " + arg)

StraightPyCall.scala

package git_log

object StraightPyCall {

  def main(args: Array[String]): Unit = {

    val commandWithNewLineInBeginning =
      """
        |python -c "import sys;sys.path.append('~/playground/octagon/bucket/pythonCheck'); from greeting import *; greet('John')"
        |""".stripMargin

    //new line stripped out from beginning and end
    val executableCommand = commandWithNewLineInBeginning.substring(1, commandWithNewLineInBeginning.length - 1)

    println("command is :-")
    println(executableCommand)

    import sys.process._

    s"$executableCommand".!!
  }
}

上述scala程序的输出是:-

command is :-
python -c "import sys;sys.path.append('~/playground/octagon/bucket/pythonCheck'); from greeting import *; greet('John')"

  File "<string>", line 1
    "import
          ^
SyntaxError: EOL while scanning string literal
Exception in thread "main" java.lang.RuntimeException: Nonzero exit value: 1
    at scala.sys.package$.error(package.scala:26)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.slurp(ProcessBuilderImpl.scala:134)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$bang$bang(ProcessBuilderImpl.scala:104)
    at git_log.StraightPyCall$.main(StraightPyCall.scala:19)
    at git_log.StraightPyCall.main(StraightPyCall.scala)

当我尝试执行打印在控制台上的命令时。它工作得很好。

python -c "import sys;sys.path.append('~/playground/octagon/bucket/pythonCheck'); from greeting import *; greet('John')"

结果:-

嘿约翰

注意:下面是 ProcessBuilder toString 表示(在调试时从堆栈跟踪复制):-

[python, -c, "import, sys;sys.path.append('/Users/mogli/jgit/code-conf/otherScripts/pythonScripts/CallRelativePyFromBash/pyscripts');, from, Greet, import, *;, greet_with_arg('John')"]

请建议,在 commandWithNewLineInBeginning 中需要修改什么以使其在 scala 中工作

【问题讨论】:

    标签: python scala function processbuilder


    【解决方案1】:

    它可以从命令行运行,因为 shell 在调用 python 命令之前会解析和解释字符串。在 Scala 代码中,ProcessBuilder 试图在没有 shell 帮助的情况下解析和解释字符串。

    我们可以帮助口译。这应该可以。

    Seq("python"
       ,"-c"
       ,"import sys;sys.path.append('~/playground/octagon/bucket/pythonCheck'); from greeting import *; greet('John')"
       ).!!
    

    如果您真的必须从完整的字符串开始,那么也许您可以在处理之前将其分解。

    例如:如果您知道模式总是“cmnd -c string”,那么这可能会起作用。

    commandWithNewLineInBeginning.replaceAll("\"","")
                                 .split("((?=-c)|(?<=-c))")
                                 .map(_.trim)
                                 .toSeq.!!
    

    【讨论】:

      猜你喜欢
      • 2012-01-23
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      相关资源
      最近更新 更多