从scala调用python脚本函数

问题描述 投票:0回答:1

尝试从scala调用python函数失败,并出现以下错误。但是当直接从命令行调用同一命令时,效果很好。

请在下面找到简化的代码段:-

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表示形式(调试时从stacktrace复制):-

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

请提出建议,在commandWithNewLineInBeginning中进行哪些修改才能使其在Scala中运行

python scala function processbuilder
1个回答
0
投票

它在命令行中起作用,因为外壳程序在调用python命令之前正在解析和解释字符串。在Scala代码中,ProcessBuilder试图在没有shell帮助的情况下解析和解释字符串。

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

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

如果确实需要从完整的字符串开始,那么也许可以在处理之前将其分解。

例如:如果您知道该模式始终为“ cmnd -c字符串”,则可能可行。

commandWithNewLineInBeginning.split("((?=-c)|(?<=-c))")
                             .map(_.trim)
                             .toSeq.!!
© www.soinside.com 2019 - 2024. All rights reserved.