This notebook sums up the changes in syntax, compared to the 'raw' usage of the COM type library. Everything the API provides out of the box is still available and is working according to the docs, but the syntax of Python provides a few shortcuts to make coding easier.
When accessing items of collection-like COM classes (like IAxisVMDomains
, IAxisVMSurfaces
, anything having an Item
method), you can use the slicing mechanism of Python. Suppose that we have an IAxisVMModel
instance called axm
. The model has several domains, each of them having the property Weight
. Let say we want to calculate the weight of all domains. The out of box solution for this would be something like
weights=[]
for i in range(axm.Surfaces.Count):
weights.append(axm.Surfaces.Item[i+1].Weight)
weight = sum(weights)
or using a list comprehension
weight = sum([axm.Surfaces.Item[i+1].Weight for i in range(axm.Surfaces.Count)])
or maybe even this
surfaces = [axm.Surfaces.Item[i+1] for i in range(axm.Surfaces.Count)]
weight = sum(map(lambda s : s.Weight, surfaces))
Anyhow, although there is nothing inherently wrong with these approaches, they clearly doesn't measure up to
# if you are new to this, the colon means 'all indices in range'
weight = sum(axm.Surfaces[:].Weight)
or
weight = sum(s.Weight for s in axm.Surfaces)
or maybe
weight = sum(map(lambda s : s.Weight, axm.Surfaces))
Notice how the loops here are carried out over the collection object itself. This is because collection types implement the so-called iterator protocol.
It is also possible to provide negative indices:
axm.Surfaces[-1].Weight # equivalent to axm.Surfaces[axm.Surfaces.Count].Weight
axm.Surfaces[-2].Weight # equivalent to axm.Surfaces[axm.Surfaces.Count - 1].Weight
Without further due, some other use cases that exploit Python's slicing mechanism:
axm.Surfaces[1, 5, 7].Weight
axm.Surfaces[1:4].Weight # equivalent to axm.Surfaces[1, 2, 3].Weight
axm.Surfaces[1:8:2].Weight # equivalent to axm.Surfaces[1, 3, 5, 7].Weight
axm.Surfaces[8:1:-2].Weight # equivalent to axm.Surfaces[8, 6, 4, 2].Weight
Furthermore, instead of typing axm.Surfaces.Count
, you can use len(axm.Surfaces)
to get the number of surfaces in the model.
Be aware here, that the index of the first item in any iterable COM object is 1, opposed to the zero-indexed nature of Python.
If you have some experience with AxisVM and COM, you know about the methods BeginUpdate
and EndUpdate
. With python, you don't need to care about this, instead you can simply use the with
statement like this
with axm as model:
# do some modification here on the model
...
When a new instace of IAxisVMApplication
is created, the type library is generated on demand. After that, the type library can be accessed as
import axisvm.com.tlb as axtlb
When creating a new interface, you can do it like
from axisvm.com.client import start_AxisVM
axvm = start_AxisVM(visible=True, daemon=True)
The keyword argument daemon=True
is a simple shortcut, equivalent to
from axisvm.com.client import start_AxisVM
import axisvm.com.tlb as axtlb
axapp = start_AxisVM(visible=True, daemon=False)
axapp.CloseOnLastReleased = True
axapp.AskCloseOnLastReleased = False
axapp.AskSaveOnLastReleased = False
axapp.ApplicationClose = axtlb.acEnableNoWarning
As a result of these settings, if the COM server is shut down, AxisVM shuts down either, hence the term daemon
. Shutting down the COM server can be done with typing
axapp.Quit()