[Pythonmac-SIG] obj in MacPython and Appscript

has hengist.podd at virgin.net
Wed Oct 26 16:05:12 CEST 2005


Zhi Peng wrote:
 
>When I used appscript, I often try to print out the object or string while I debug the program. For example:
>cs = app('TextEdit').documents[1].paragraphs[1]
>print cs
>I assumed that cs should be anObject of paragraphs.
>But it print out as
> 
>app('TextEdit').documents[1].paragraphs[1]
> 
>instead of specific python object.

In fact, this is a specific python object, just not the one you expected. It's an instance of appscript's Specifier class, which represents a first-class query identifying the first paragraph of the first document of the TextEdit application. Run 'print type(cs)' to see this. Like a lot of Python objects, Specifier instances use their __repr__ method to return a meaningful representation of itself ("app('TextEdit').documents[1].paragraphs[1] ") rather than a literal one ("<class 'appscript.specifier.Specifier'>"). What it doesn't do is resolve this query itself a-la AppleScript's "implicit get"; you have to command it to do so yourself.

Please bear in mind that appscript is mostly just a big lump of OO-like syntactic sugar atop a procedural+query driven API, and the rules by which it operates are not the same as either AppleScript's (for application scripting) or Python's (for object-oriented programming). This point is made in the appscript manual, although I'm still trying to find a big enough font to display it in. ;)


>If one would like to get the actual
>reference of the paragraphs[1] object, what should I do? Anyone knew?
>if one uses following, it may get sth for 'TextEdit'
>app('TextEdit').documents[1].paragraphs[1].get()
> 
>But some other application does not have 'get' for documents[1] or
>paragraphs[1]. In this case, is there way that I can catch the object?

Not all applications bother to list get() and set() commands in their terminology documentation, but as long as they have an object model they will respond to these commands - where necessary, appscript will provide default definitions.


>For example, in Adobe InDesign CS2, I could have
> 
> 
>cs = app('Adobe InDesign CS2')
>doc=cs.open("mydoc.indd") <--- just example
>doc = cs.active_document
>page = doc.pages[1]
>print page                  <----- this does not show object

As stated above, it will show you the representation of the Specifier instance assigned to the 'page' variable.


>anObject=page.get()  <----- this may raise exception
 
This should work, assuming that you do actually have an active document with at least one page in it, and ID doesn't have any bugs that prevent it resolving that reference correctly. That said, I do remember ID's dictionary being particularly warty with respect to get() and set(), defining both standard AND non-standard versions of these commands. I can't remember how well older versions of appscript resolved this problem, and I don't have a copy of ID here to test on, but the latest version will correctly disambiguate things by appending underscores to the non-standard definitions so they appear as get_() and set_(), allowing the standard get() and set() to be used as normal.

The source distribution is at <http://freespace.virgin.net/hamish.sanderson/appscript_source.html> if you want to remove your existing installation (which I assume was created by Appscript Installer, which is a couple releases behind) and build a fresh installation from scratch. Sorry it's such a pain in the butt, but I will get an up-to-date binary installer done at some point; it's just a matter of finding the time, etc.


>2. By the way, I get a little confused with following command
>application.make(...) -- Make a new element

'make' is often one of the worst-documented commands that application scripters will encounter, so you're by no means alone in your confusion. Go file a feature request for better documentation with the application's developer, and meantime get used to figuring it out by asking other users, pulling apart any sample scripts you can find, and plain old trial-and-error.


>[new=Type] -- The class of the item to be created
>[at=InsertionRef] -- The location at which to insert the item
>[with_data=Record] -- The initial data for the item
>[with_properties=Record] -- Initial values for properties of the new object
>Result: Reference -- The new object(s)
>
>I guess that 'new' may be sth like new=text_frame or new=document

That should read:

    new=k.text_frame

or:

    new=k.document

since all Apple Event Manager-defined types and application-defined types/classes exist as attributes of the k namespace.


>at=cs.documents[1].sth
>What was the with_data=Record and with_properties? 
 
The 'with_properties' parameter allows you to specify initial values for some or [depending on the application] all of the properties of the object being created. For example:

	app('TextEdit').documents.end.make(
		new=k.document,
		with_properties={k.text: 'Hello World'})

will create a new document in TextEdit and set its text property to 'Hello World'. This is simpler than sending two separate commands, one to create the object and another to initialise its state:

	doc = app('TextEdit').documents.end.make(new=k.document)
	doc.text.set('Hello World')


The 'with_data' parameter is a bit of a stinker. Basically you use it when you want to set the value of an element itself, but it's invariably undocumented so figuring out when it it can/should be used and what sort of data it takes to be is all down to guesswork and folk knowledge. It's not something that's used all that often, but a good example is creating a new paragraph in a TextEdit document, where you use it to specify the [plain] text for that paragraph:

	app('TextEdit').documents[1].paragraphs.end.make(
		new=k.paragraph,
		with_data='Hello World\n')

HTH

has
-- 
http://freespace.virgin.net/hamish.sanderson/


More information about the Pythonmac-SIG mailing list