16

有什么方法可以在不使用osascript命令行实用程序或appscript的情况下从 python 执行(并获得结果)AppleScript 代码(我真的不想使用(我认为?),因为它不再被开发/支持/推荐)?

理由:在我刚刚发布的另一个问题中,我描述了我在运行一些 AppleScript 时遇到的一种奇怪/不受欢迎的行为osascript。因为我实际上是从 python 脚本调用它,所以我想知道是否有办法osascript完全路由,因为这似乎是问题所在 - 但 appscript(显而易见的选择?)现在看起来有风险......

4

3 回答 3

24

您可以使用 PyObjC 桥:

>>> from Foundation import *
>>> s = NSAppleScript.alloc().initWithSource_("tell app \"Finder\" to activate")
>>> s.executeAndReturnError_(None)
于 2013-04-17T17:16:50.697 回答
22

PyPI 是你的朋友...

http://pypi.python.org/pypi/py-applescript

例子:

import applescript

scpt = applescript.AppleScript('''
    on run {arg1, arg2}
        say arg1 & " " & arg2
    end run

    on foo()
        return "bar"
    end foo

    on Baz(x, y)
        return x * y
    end bar
''')

print(scpt.run('Hello', 'World')) #-> None
print(scpt.call('foo')) #-> "bar"
print(scpt.call('Baz', 3, 5)) #-> 15
于 2013-04-19T09:36:14.470 回答
2

如果希望在您的 python 代码中执行“自动化的 Javascript”(applescript 的继任者),请执行以下操作:

script = None

def compileScript():
    from OSAKit import OSAScript, OSALanguage

    scriptPath = "path/to/file.jxa"
    scriptContents = open(scriptPath, mode="r").read()
    javascriptLanguage = OSALanguage.languageForName_("JavaScript")

    script = OSAScript.alloc().initWithSource_language_(scriptContents, javascriptLanguage)
    (success, err) = script.compileAndReturnError_(None)

    # should only occur if jxa is incorrectly written
    if not success:
        raise Exception("error compiling jxa script")

    return script

def execute():
    # use a global variable to cache the compiled script for performance
    global script
    if not script:
        script = compileScript()

    (result, err) = script.executeAndReturnError_(None)

    if err:
        # example error structure:
        # {
        #     NSLocalizedDescription = "Error: Error: Can't get object.";
        #     NSLocalizedFailureReason = "Error: Error: Can't get object.";
        #     OSAScriptErrorBriefMessageKey = "Error: Error: Can't get object.";
        #     OSAScriptErrorMessageKey = "Error: Error: Can't get object.";
        #     OSAScriptErrorNumberKey = "-1728";
        #     OSAScriptErrorRangeKey = "NSRange: {0, 0}";
        # }

        raise Exception("jxa error: {}".format(err["NSLocalizedDescription"]))
    
    # assumes your jxa script returns JSON
    return json.loads(result.stringValue())
于 2021-05-05T17:56:21.003 回答