【问题标题】:Python COM Interop - Factory PatternPython COM 互操作 - 工厂模式
【发布时间】:2018-12-12 02:19:43
【问题描述】:

我有两个 python 类,它们都可以使用 COM 互操作机制独立于 VBA 编写脚本。但我希望一个控制另一个的创建,在父子模式或工厂模式中。

我已经尝试过但无法开始工作,我已经提炼到下面的 MCRE。我是 Python 的新手。我想知道是否有办法继承一个 mixin,它会给类提供必要的 COM 互操作方法。

好的,所以我创建了一个 MCRE,这里是 Python 代码,必须至少从具有管理员权限的命令行运行一个才能完成 COM 注册(此后不需要管理员)。

import win32com.client


class MyParent(object):
    _reg_clsid_ = "{C61A7C6E-B657-4D55-AD36-8850B2E501AC}"
    _reg_progid_ = 'PythonInVBA.MyParent'
    _public_methods_ = ['Greet', 'GetChild']

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = MyChild()
        self.child.SetName("foo")

    def Greet(self):
        return "Hello world"

    def GetChild(self):
        return self.child


class MyChild(object):
    _reg_clsid_ = "{15DAAEE2-3A37-4DE1-9973-CCD011DF4888}"
    _reg_progid_ = 'PythonInVBA.MyChild'
    _public_methods_ = ['Initialize', 'GetName', 'SetName']

    def __init__(self):  # Rules of Com say paramerless constructors
        pass

    def GetName(self):
        return self.name

    def SetName(self, sName):
        self.name = sName

if __name__ == '__main__':
    print ("Registering COM servers...")
    import win32com.server.register
    win32com.server.register.UseCommandLine(MyParent)
    win32com.server.register.UseCommandLine(MyChild)

这里是 VBA 代码,前两个子程序工作,但第三个失败。

Option Explicit

Sub Test_MyParent_OnItsOwn()
    On Error GoTo ErrHand:

    Dim objMyParent As Object
    Set objMyParent = VBA.CreateObject("PythonInVBA.MyParent")
    Debug.Assert objMyParent.Greet = "Hello world"
    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub

Sub Test_MyChild_OnItsOwn()
    On Error GoTo ErrHand:

    Dim objMyChild As Object
    Set objMyChild = VBA.CreateObject("PythonInVBA.MyChild")

    objMyChild.SetName "Kevin"
    Debug.Assert objMyChild.GetName = "Kevin"
    ''' success MyChild is scriptable
    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub


Sub Test_MyParent_Returning_MyChild()
    On Error GoTo ErrHand:

    Dim objMyParent As Object
    Set objMyParent = VBA.CreateObject("PythonInVBA.MyParent")

    Dim objMyChild As Object

    '* errors with Unexpected Python Error: TypeError: Objects of type 'MyChild' can not be converted to a COM VARIANT (but obtaining the buffer() of this object could)
    Set objMyChild = objMyParent.GetChild()

    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub

【问题讨论】:

  • 此后不需要管理员 - 取决于。自注册以来,班级或其成员是否发生了变化?如果成员的顺序改变了,他们的DISPID就会改变。
  • Matt ('s Mug),好的,继续,像往常一样在管理员下运行它。
  • 哦,我不做 Python! [很遗憾! =) ...只是抓住稻草,不知道为什么它不起作用。
  • @Mat:你不知道自己错过了什么,我在 Python/VBA 上写了整整一个月的博文exceldevelopmentplatform.blogspot.com/2018/06/…
  • 我认为我永远不会被卖给 Python。 C# 完成了我需要做的所有事情,包括 COM 互操作......有效 (wink-wink ;-)

标签: python vba excel com com-interop


【解决方案1】:

我把评论的内容转换成了答案。

这是因为 MyChild 没有在 MyParent 中生成为 COM 对象。
如果您按以下方式更改它,它将起作用。

原文:

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = MyChild()
        self.child.SetName("foo")

修改:

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = win32com.client.Dispatch("PythonInVBA.MyChild")
        self.child.SetName("foo")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-27
    • 2011-03-08
    • 2010-12-14
    • 1970-01-01
    • 2011-04-13
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多