从 Scala 调用 python 脚本函数
call python script function from scala
尝试从 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')"
结果:-
hey 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 中运行
它在命令行中工作,因为 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.!!
尝试从 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')"
结果:-
hey 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 中运行
它在命令行中工作,因为 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.!!