简体   繁体   English

如何在 Python 脚本中嵌入 AppleScript?

[英]How do I embed an AppleScript in a Python script?

I am trying to embed an AppleScript in a Python script.我正在尝试在 Python 脚本中嵌入 AppleScript。 I don't want to have to save the AppleScript as a file and then load it in my Python script.我不想将 AppleScript 保存为文件,然后将其加载到我的 Python 脚本中。 Is there a way to enter the AppleScript as a string in Python and have Python execute the AppleScript?有没有办法在 Python 中将 AppleScript 作为字符串输入并让 Python 执行 AppleScript? Thanks a bunch.谢谢一堆。

Here is my script: import subprocess import re import os这是我的脚本: import subprocess import re import os

def get_window_title():
    cmd = """osascript<<END
    tell application "System Events"
        set frontApp to name of first application process whose frontmost is true
    end tell
    tell application frontApp
        if the (count of windows) is not 0 then
            set window_name to name of front window
        end if
    end tell
    return window_name
    END"""

    p = subprocess.Popen(cmd, shell=True)
    p.terminate()
    return p

def get_class_name(input_str):
    re_expression = re.compile(r"(\w+)\.java")
    full_match = re_expression.search(input_str)
    class_name = full_match.group(1)
    return class_name

print get_window_title()

Use subprocess :使用子流程

from subprocess import Popen, PIPE

scpt = '''
    on run {x, y}
        return x + y
    end run'''
args = ['2', '2']

p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)

Example 3 in this article suggests: 本文中的示例 3 建议:

#!/usr/bin/env python
#sleepy-mac.py
#makes my mac very sleepy

import os
cmd = """osascript -e 'tell app "Finder" to sleep'"""
def stupidtrick():
     os.system(cmd)
stupidtrick()

These days, however, subsystem.Popen is usually preferred over os.system (the article is from three years ago, when nobody screamed on seeing an os.system call;-).然而,现在, subsystem.Popen通常比os.systemos.system (这篇文章来自三年前,当时没有人看到os.system调用时尖叫;-)。

In python 3 it would be slightly different:在python 3中它会略有不同:

script = 'tell "some application" to do something'
p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
stdout, stderr = p.communicate(script)

Popen now expects a byte-like object, to pass a string, the universal_newlines=True parameter is needed. Popen 现在需要一个类似字节的对象,要传递一个字符串,需要universal_newlines=True参数。

Here's a simple python3 synchronous example, if you want your python code not to wait for Applescript to finish.这是一个简单的python3同步示例,如果您希望您的python代码不等待Applescript完成。 In this example, both say commands are executed in parallel.在这个例子中,两个say命令都是并行执行的。

from subprocess import Popen

def exec_applescript(script):
    p = Popen(['osascript', '-e', script])

exec_applescript('say "I am singing la la la la" using "Alex" speaking rate 140 pitch 60')
exec_applescript('say "Still singing, hahaha" using "Alex" speaking rate 140 pitch 66')

See https://pypi.org/project/applescript/https://pypi.org/project/applescript/

import applescript
resp = applescript.tell.app("System Events",'''
set frontApp to name of first application process whose frontmost is true
return "Done"
''')
assert resp.code == 0, resp.err
print(resp.out)

etc. Most of suggestions, including "applescript" I quoted, are missing one important setting to osascript -- setting an -s option to "s", otherwise you will be having difficulty parsing the output.等等。大多数建议,包括我引用的“applescript”,都缺少 osascript 的一个重要设置——将 -s 选项设置为“s”,否则您将难以解析输出。

Here's a generic function in python.这是python中的一个通用函数。 Just pass your applescript code with/without args and get back the value as a string.只需使用/不使用 args 传递您的 Applescript 代码,然后将值作为字符串返回。 Thanks to this answer.感谢这个答案。

from subprocess import Popen, PIPE

def run_this_scpt(scpt, args=[]):
    p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate(scpt)
    return stdout

#Example of how to run it.
run_this_scpt("""tell application "System Events" to keystroke "m" using {command down}""")

#Example of how to run with args.
run_this_scpt('''
    on run {x, y}
        return x + y
    end run''', ['2', '2'])

Rather than embedding AppleScript, I would instead use appscript .我不会嵌入 AppleScript,而是使用appscript I've never used the Python version, but it was very nice in Ruby.我从未使用过 Python 版本,但它在 Ruby 中非常好。 And make sure that, if you're installing it on Snow Leopard, you have the latest version of XCode.并确保,如果您在 Snow Leopard 上安装它,您拥有最新版本的 XCode。 However, I've so far been unable to install it on Snow Leopard.但是,到目前为止,我一直无法在 Snow Leopard 上安装它。 But I've only had Snow Leopard for ~1 day, so your mileage may vary.但我只吃雪豹大约 1 天,所以你的里程可能会有所不同。

You can use os.system :您可以使用os.system

import os
os.system('''
    osascript -e 
     '[{YOUR SCRIPT}]'
     '[{GOES HERE}]'
    ''')

or, as suggested by Alex Martelli you can use a variable:或者,正如 Alex Martelli 所建议的,您可以使用一个变量:

import os
script = '''
    [{YOUR SCRIPT}]
    [{GOES HERE}]
'''
os.system('osascript -e ' + script)

subprocess.run() is now preferred over subprocess.popen() . subprocess.run() 现在优于subprocess.popen() Here is a pretty simple way to run AppleScript code and get the results back.这是运行 AppleScript 代码并返回结果的一种非常简单的方法。

import subprocess

def get_window_title():
    cmd = """
        tell application "System Events"
            set frontApp to name of first application process whose frontmost is true
        end tell
        tell application frontApp
            if the (count of windows) is not 0 then
                set window_name to name of front window
            end if
        end tell
        return window_name
    """
    result = subprocess.run(['osascript', '-e', cmd], capture_output=True)
    return result.stdout

print(get_window_title())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM