applescript 元素、类和对象
我正在编写一个 applescript 来自动化 Aperture 中的一些乏味的工作,并且我在理解该语言的一些特殊性方面经历了一段痛苦的时光。特别是,我在处理集合(列表和元素)时遇到了很大的困难。我对包含集合以及将命令应用于集合中的元素的对象说明符感到困惑。此外,我对对象说明符的奇怪差异感到困惑,这些差异在类中按类引用对象元素时似乎表现不同,好吧,让我向您展示。
这是脚本的开头。
prop Movies : {}
tell Application "Aperture"
set Movies to every image version whose name of every keywords contains "Movie"
end tell
length of Movies -- result => 601
Aperture 中的application
对象包含图像版本
的元素集合。 image version
对象包含 keyword
的元素集合。 keyword
是具有 name
和 id
属性的对象/列表。
因此,全局脚本属性 Movies
现在包含我的 Aperture 库中实际上是视频的所有image version
对象。现在,当我尝试执行此操作时:
repeat with movie in Movies
log ("Movie name is '" & name of movie & "'.")
log (" the class of this object is '" & class of movie & "'.")
end
正如预期的那样,输出是:
Movie name is 'MOV03510.MPG'.
the class of this object is 'image version'.
Movie name is 'MOV00945'.
the class of this object is 'image version'.
Movie name is 'MOV03228.MPG'.
the class of this object is 'image version'.
Movie name is 'MOV02448'.
the class of this object is 'image version'.
...
但是,我一直困惑于如何访问这些图像版本
中的元素集合。当我这样做时:
repeat with movie in Movies
log ("Movie name is '" & name of movie & "'.")
log (" the class of this object is '" & class of movie & "'.")
set kwnamelist to name of every keyword in movie
if kwnamelist contains "Movie"
log (" Yes, '" & name of movie & "' is indeed a video.")
end if
end
给了我
find_videos.applescript:1089:1096: script error: Expected class name but found identifier. (-2741)
错误,对我来说,听起来像 applescript 被对象说明符电影中每个关键字的名称
所混淆。但是,我对此感到如此困惑的原因是,如果我编写此代码:
tell Application "Aperture"
repeat with imageind from 1 to 1000
set img to item imageind of image versions
tell me to log ("Image name is '" & name of img & "'.")
tell me to log (" the class of this object is '" & class of img & "'.")
set kwnamelist to name of every keyword in img
if kwnamelist contains "Movie"
tell me to log (" '" & name of img & "' is actually a video!")
end if
end
end tell
那么我会得到预期的输出:
...
Image name is 'DSC_4650'.
the class of this object is 'image version'.
Image name is '104-0487_IMG'.
the class of this object is 'image version'.
Image name is 'MOV02978.MPG'.
the class of this object is 'image version'.
'MOV02978.MPG' is actually a video!
Image name is '108-0833_IMG'.
the class of this object is 'image version'.
...
任何人都可以告诉我我的对象说明符出了什么问题吗?为什么当图像版本
在一个上下文中时,我基本上可以将get name
应用于img中的每个关键字
,但我不能在不同的背景下?我在这里缺少什么吗? keyword
类是否属于 Aperture application
对象的内部?如果是这种情况,我将如何指定诸如 application::keyword
之类的内容?
更新:
我已经解决了这个特定问题,但如果有人能够准确解释为什么这个解决它,我真的很感激。我这样做了:
tell Application "Aperture"
repeat with movie in Movies
tell me to log ("Movie name is '" & name of movie & "'.")
tell me to log (" the class of this object is '" & class of movie & "'.")
set kwnamelist to name of every keyword in movie
if kwnamelist contains "Movie"
tell me to log (" Yes, '" & name of movie & "' is indeed a video.")
end if
end
end tell
给出了预期的输出:
...
Movie name is 'IMG_0359'.
the class of this object is 'image version'.
Yes, 'IMG_0359' is indeed a video.
Movie name is 'MOV02921.MPG'.
the class of this object is 'image version'.
Yes, 'MOV02921.MPG' is indeed a video.
Movie name is 'MOV02249'.
the class of this object is 'image version'.
Yes, 'MOV02249' is indeed a video.
...
这里似乎存在一个非常特殊的范围问题。有人可以向我解释一下 keyword
对象如何在这个新版本中处于范围内,但在之前版本中超出了范围(我们不在 tell
块中)吗?我认为 tell
块只是用于指示没有直接参数的命令?它们也确定类型范围吗?或者在对象说明符的构造/执行中是否隐藏了一个命令,该命令取决于发送到应用程序“Aperture”
对象?
I'm writing an applescript to automate some tedious work in Aperture, and I'm having a hell of a time understanding some of the peculiarities of the language. In particular, I'm having a really difficult time dealing with collections (lists and elements). I'm stumped by object specifiers that include collections and applying commands to elements in a collection. Moreover, I'm confused by strange differences in object specifiers that seem to behave differently when referring to object elements by their class within a class versus, well, let me show you.
Here's the beginning of a script.
prop Movies : {}
tell Application "Aperture"
set Movies to every image version whose name of every keywords contains "Movie"
end tell
length of Movies -- result => 601
The application
object in Aperture contains an elements collection of image version
s. image version
objects contain an elements collection of keyword
s. keyword
s are objects/lists with a name
and id
property.
So the global script property Movies
now contains all of the image version
objects in my Aperture library that are actually videos. Now, when I try to do this:
repeat with movie in Movies
log ("Movie name is '" & name of movie & "'.")
log (" the class of this object is '" & class of movie & "'.")
end
the output, as expected, is:
Movie name is 'MOV03510.MPG'.
the class of this object is 'image version'.
Movie name is 'MOV00945'.
the class of this object is 'image version'.
Movie name is 'MOV03228.MPG'.
the class of this object is 'image version'.
Movie name is 'MOV02448'.
the class of this object is 'image version'.
...
However, I'm stuck with how to access an elements collection within those image version
s. When I do this:
repeat with movie in Movies
log ("Movie name is '" & name of movie & "'.")
log (" the class of this object is '" & class of movie & "'.")
set kwnamelist to name of every keyword in movie
if kwnamelist contains "Movie"
log (" Yes, '" & name of movie & "' is indeed a video.")
end if
end
gives me
find_videos.applescript:1089:1096: script error: Expected class name but found identifier. (-2741)
The error, to me, sounds like applescript is confused by the object specifier name of every keyword in movie
. BUT, the reason I'm so confused about this is that if I write this code:
tell Application "Aperture"
repeat with imageind from 1 to 1000
set img to item imageind of image versions
tell me to log ("Image name is '" & name of img & "'.")
tell me to log (" the class of this object is '" & class of img & "'.")
set kwnamelist to name of every keyword in img
if kwnamelist contains "Movie"
tell me to log (" '" & name of img & "' is actually a video!")
end if
end
end tell
then I get the expected output:
...
Image name is 'DSC_4650'.
the class of this object is 'image version'.
Image name is '104-0487_IMG'.
the class of this object is 'image version'.
Image name is 'MOV02978.MPG'.
the class of this object is 'image version'.
'MOV02978.MPG' is actually a video!
Image name is '108-0833_IMG'.
the class of this object is 'image version'.
...
Can anyone tell me what's wrong with my object specifier? Why is it that I can essentially apply get name
to every keyword in img
when the image version
is in one context, but I can't in a different context? Is there something I'm missing here? Is it that the keyword
class is internal to the Aperture application
object? How would I specify something like application::keyword
if that's the case?
UPDATE:
I've solved this particular problem, but I'd really appreciate it if someone could explain exactly why this solves it. I did this:
tell Application "Aperture"
repeat with movie in Movies
tell me to log ("Movie name is '" & name of movie & "'.")
tell me to log (" the class of this object is '" & class of movie & "'.")
set kwnamelist to name of every keyword in movie
if kwnamelist contains "Movie"
tell me to log (" Yes, '" & name of movie & "' is indeed a video.")
end if
end
end tell
gives the expected output:
...
Movie name is 'IMG_0359'.
the class of this object is 'image version'.
Yes, 'IMG_0359' is indeed a video.
Movie name is 'MOV02921.MPG'.
the class of this object is 'image version'.
Yes, 'MOV02921.MPG' is indeed a video.
Movie name is 'MOV02249'.
the class of this object is 'image version'.
Yes, 'MOV02249' is indeed a video.
...
It seems like there's a very peculiar scope issue at work here. Could someone explain to me how keyword
objects are in scope in this new version, but out of scope in the previous version where we weren't in a tell
block? I thought that tell
blocks were just for directing commands without direct parameters? Do they determine type scope as well? Or is there a command hidden somewhere here in the construction/execution of the object specifier that depends on getting sent to the Application "Aperture"
object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果我正确理解你的问题的核心 - 因为你已经解决了实际部分,扭曲的取消引用,这对于苹果脚本人员来说有点老栗子 - 你必须只在相关的告诉块中使用术语,所以如果你的应用程序(Aperture)提供术语“关键字”,除非您位于
告诉应用程序“Aperture”
块内,否则您不能引用“关键字”。或者,如果由于某种原因您想使用给定应用程序中的术语而不使用告诉块,您可以像这样包装代码:
If I understand the core of your question correctly - because you have solved the practical part, screwy dereferencing, which is a bit of an old chestnut for applescripters - you must only use terminology inside the relevant tell blocks, so if your application (Aperture) supplies the terminology "keyword", you can't refer to "keyword" unless you are inside a
tell application "Aperture"
block.OR if for some reason you want to use terminology from a given app without using a tell block, you can wrap your code like this:
不幸的是,Applescript 是相当有趣的,而且经常会出现碰碰运气的情况。在这种情况下,
与列表中的项目重复
,项目是对内容的引用,而不是内容本身。 AppleScript 通常会为您取消引用它,但并非总是如此。通常,我总是使用repeat with x from 1 to count
方法来避免此问题。Applescript is rather funny like this unfortunately and often times it's hit or miss. In this case
repeat with item in list
, item is a reference to the contents, not the contents itself. Often times AppleScript will dereference this for you, but not always. Typically I always use therepeat with x from 1 to count
method to avoid this problem.关于 Aperture 关键字脚本
Aperture 3 中的关键字脚本非常不直观。以下是我了解到的内容:
parents
属性的值只是不带名称的 id,如果关键字不在顶层,则为名称后面的选项卡。animage 的关键字 1!= anImage 的关键字 1
。anImage
添加名为aName
和父级theParents
的关键字的方法是告诉 anImage 使用属性 {name: 创建新关键字aName, 父母:theParents, id:aName&tab&theParents}
请参阅 我的条目在这里以获得更完整的解释以及添加和删除处理程序。
About scripting Aperture keywords
Keyword scripting in Aperture 3 is quite unintuitive. Here's what Ive learned:
id
is a string with the path from the keyword name up to its top-level parent, with each parent's name preceded by a tab.parents
property is just the id without the name and, if the keyword is not at the top-level, the tab following the name.keyword 1 of animage != keyword 1 of anImage
.anImage
with nameaName
and parentstheParents
istell anImage to make new keyword with properties {name:aName, parents:theParents, id:aName&tab&theParents}
See my entry here for a fuller explanation plus add and remove handlers.