Python win32com和2维数组

joo*_*jaa 3 python coordinates multidimensional-array win32com

当使用python和win32com自动化软件形式时,Adobe遇到了传递2d坐标数组的问题.如果看一下Adobe为visual basic(VB)提供的代码就很简单了.在Illustrator中绘制线条的简化示例如下所示:

Set appObj = CreateObject("Illustrator.Application")
Set docObj = appObj.Documents.Add

Set pathItem = docObj.PathItems.Add
    pathItem.SetEntirePath Array(Array(0.0, 0.0), Array(20.0, 20.0))
Run Code Online (Sandbox Code Playgroud)

现在天真的假设是VB代码可以通过如下转换成python:

from win32com.client import Dispatch

appObj = Dispatch("Illustrator.Application")  
docObj = appObj.Documents.Add()

pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( [ [0.0,0.0], [20.0,20.0] ] )
Run Code Online (Sandbox Code Playgroud)

显然,这并不容易,python发出错误说"只支持维度为1的数组".现在我知道阵列数组和二维数组之间存在差异.所以问题是我如何强制python制作一个正确的数组呢?

我尝试制作自己的VARIANT类型,但失败了.我也看过这个问题.任何人都有同样的问题,可以解决一些问题吗?

PS:

我知道使用以下方法可以避免这个问题:

pathItem = docObj.PathItems.Add()
for point in (  [0.0,0.0], [20.0,20.0] ):
    pp = pathItem.PathPoints.Add() 
    pp.Anchor = point
Run Code Online (Sandbox Code Playgroud)

但是有类似的情况,这实际上并不起作用.无论如何,重点是编写关于移植给学生的指导方针,以便更接近原始意图.

joo*_*jaa 7

这是一个实际使用win32com模块的替代解决方案.碰巧的是,IllustratorPhotoshop的数组类型是变种类型的单一数组.变体类型也是数组.还有其他应用程序,如solidworks,使用相同的策略.您可以使用以下代码强制win32com创建变体类型:

from win32com.client import VARIANT
from pythoncom import VT_VARIANT

def variant(data):
    return VARIANT(VT_VARIANT, data)
Run Code Online (Sandbox Code Playgroud)

方便的是,人们不需要总是在任何地方键入变量,因此您可以只使用python数组并使用以下内容创建每个子元素变体:

import collections

def vararr(*data):
    if (  len(data) == 1 and 
          isinstance(data, collections.Iterable) ):
        data = data[0]
    return map(variant, data)
Run Code Online (Sandbox Code Playgroud)

所以最后我的完整代码如下:

from win32com.client import Dispatch, VARIANT
from pythoncom import VT_VARIANT
import collections


appObj = Dispatch("Illustrator.Application")  
docObj = appObj.Documents.Add()

def variant(data):
    return VARIANT(VT_VARIANT, data)

def vararr(*data):
    if (  len(data) == 1 and 
          isinstance(data, collections.Iterable) ):
        data = data[0]
    return map(variant, data)

pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( vararr( [0.0,0.0], [20.0,20.0] )  )

#or you can have a iterable of iterables
pathItem = docObj.PathItems.Add()
pathItem.SetEntirePath( vararr( [[30.0,10.0], [60.0,60.0]] )  )
Run Code Online (Sandbox Code Playgroud)

是的,这可以用comtypes完成,但这回答了我在win32com中如何做到的真正问题.除了有理由使用win32com,例如能够生成常量.所以经过很长一段时间,我终于找到了一个真正困惑我的问题的答案.希望这有助于某人.