473,748 Members | 2,361 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Python COM iterator

Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?

Example:

Python COM object

class foo:
_public_methods _=['next']

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]

def next(self):
try: return self.numbers.po p(0)
except IndexError:
#
# Normally in Python I would do this, but that raises a
# COMexception when used in a COM object.
#
raise StopIteration

def __iter__(self):
return self
I want to be able to write something like (VB):

oFOO=foo()
for each n in oFOO
'
' Do something with n
'
next

Seems like there should be a way. Hope explanation is clear enough.

Regards, Larry

Apr 17 '07 #1
9 2305
On Tue, 2007-04-17 at 16:54 -0500, Larry Bates wrote:
Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?
I don't use COM, VB, or Delphi, but Google turned up these two
references:
http://msdn.microsoft.com/library/de...ingForEach.asp http://17slon.com/blogs/gabr/2007/03...rs-part-1.html

Judging from those links, an object is iterable in VB and Delphi (or as
they call it, it is enumerable) if it exposes a GetEnumerator method
that returns an enumerator. The enumerator in turn needs to expose a
MoveNext method and a Current property.

Assuming that the Enumerable and the Enumerator are allowed to be the
same object, you'll probably need code that looks something like this:

class foo:
_public_methods _=['GetEnumerator' ,'MoveNext']
# You'll need to figure out how to expose "self.Curre nt"

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]
self.Current = None

def MoveNext(self):
try:
self.Current = self.numbers.po p(0)
return True
except IndexError:
return False

def GetEnumerator(s elf):
return self

Good luck,

Carsten.
Apr 18 '07 #2
Carsten Haese wrote:
On Tue, 2007-04-17 at 16:54 -0500, Larry Bates wrote:
>Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?

I don't use COM, VB, or Delphi, but Google turned up these two
references:
http://msdn.microsoft.com/library/de...ingForEach.asp http://17slon.com/blogs/gabr/2007/03...rs-part-1.html

Judging from those links, an object is iterable in VB and Delphi (or as
they call it, it is enumerable) if it exposes a GetEnumerator method
that returns an enumerator. The enumerator in turn needs to expose a
MoveNext method and a Current property.

Assuming that the Enumerable and the Enumerator are allowed to be the
same object, you'll probably need code that looks something like this:

class foo:
_public_methods _=['GetEnumerator' ,'MoveNext']
# You'll need to figure out how to expose "self.Curre nt"

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]
self.Current = None

def MoveNext(self):
try:
self.Current = self.numbers.po p(0)
return True
except IndexError:
return False

def GetEnumerator(s elf):
return self

Good luck,

Carsten.

I looked over the links and what you have proposed seems to make sense, but
I can't make it work. I have the following class defined and registered.

class foo:

_public_methods _=['GetEnumerator' ,'MoveNext']
_public_attrs_=['Current']
_reg_clsid_='{F C2A0E7B-E428-4414-B1C4-60373BB12102}'
_reg_progid_="S yscon.foo"

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]
self.Current = None

def MoveNext(self):
try:
self.Current = self.numbers.po p(0)
rtnval=True

except IndexError:
self.Current=No ne
rtnval=False

def GetEnumerator(s elf):
return self
Then I do:
>>import win32com.client
typelib='Sysc on.foo'
F=win32com.cl ient.Dispatch(t ypelib)
for x in F:
.... print x
....
Traceback (most recent call last):
File "<interacti ve input>", line 1, in <module>
File "C:\Python25\li b\site-packages\win32c om\client\dynam ic.py", line 228, in
__getitem__
raise TypeError, "This object does not support enumeration"
TypeError: This object does not support enumeration
>>>
but this works fine:
>>F.MoveNext( )
F.Current
1
>>F.MoveNext( )
F.Current
2
>>>

I'm stumped.

-Larry
Apr 18 '07 #3
>[...]
On Tue, 2007-04-17 at 16:54 -0500, Larry Bates wrote:
Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?
[...]
After more googling, staring at win32com's code, and a fair bit of trial
and error, I've come up with the following working example:

# server.py
import pythoncom

class HelloWorld:
_reg_clsid_ = "{CAB8BED1-9174-4AAD-ABC5-F377951CB71B}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestSer ver"
_public_methods _ = ['Next']
_com_interfaces _ = [pythoncom.IID_I EnumVARIANT]

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]

def Next(self, count):
assert count==1
try:
return (self.numbers.p op(0),)
except IndexError:
return ()

def _NewEnum(self):
import win32com.server .util
return win32com.server .util.wrap(self )

if __name__=='__ma in__':
import win32com.server .register
win32com.server .register.UseCo mmandLine(Hello World)

# client.py
import win32com.client
comobj = win32com.client .Dispatch("Pyth on.TestServer")
for x in comobj:
print x

This works for me on Python 2.5 and pywin32 Build 210, but I don't know
whether clients in VB or Delphi are able to use this iterator.

-Carsten
Apr 19 '07 #4
Carsten Haese wrote:
>[...]
>>On Tue, 2007-04-17 at 16:54 -0500, Larry Bates wrote:
Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?
[...]

After more googling, staring at win32com's code, and a fair bit of trial
and error, I've come up with the following working example:

# server.py
import pythoncom

class HelloWorld:
_reg_clsid_ = "{CAB8BED1-9174-4AAD-ABC5-F377951CB71B}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestSer ver"
_public_methods _ = ['Next']
_com_interfaces _ = [pythoncom.IID_I EnumVARIANT]

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]

def Next(self, count):
assert count==1
try:
return (self.numbers.p op(0),)
except IndexError:
return ()

def _NewEnum(self):
import win32com.server .util
return win32com.server .util.wrap(self )

if __name__=='__ma in__':
import win32com.server .register
win32com.server .register.UseCo mmandLine(Hello World)

# client.py
import win32com.client
comobj = win32com.client .Dispatch("Pyth on.TestServer")
for x in comobj:
print x

This works for me on Python 2.5 and pywin32 Build 210, but I don't know
whether clients in VB or Delphi are able to use this iterator.

-Carsten

I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.

Thanks loads.

-Larry
Apr 19 '07 #5
Carsten Haese wrote:
>[...]
>>On Tue, 2007-04-17 at 16:54 -0500, Larry Bates wrote:
Does anyone know if there is a way to make a Python COM object
act like a proper iterator in VB/Delphi?
[...]

After more googling, staring at win32com's code, and a fair bit of trial
and error, I've come up with the following working example:

# server.py
import pythoncom

class HelloWorld:
_reg_clsid_ = "{CAB8BED1-9174-4AAD-ABC5-F377951CB71B}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestSer ver"
_public_methods _ = ['Next']
_com_interfaces _ = [pythoncom.IID_I EnumVARIANT]

def __init__(self):
self.numbers=[1,2,3,4,5,6,7,8]

def Next(self, count):
assert count==1
try:
return (self.numbers.p op(0),)
except IndexError:
return ()

def _NewEnum(self):
import win32com.server .util
return win32com.server .util.wrap(self )

if __name__=='__ma in__':
import win32com.server .register
win32com.server .register.UseCo mmandLine(Hello World)

# client.py
import win32com.client
comobj = win32com.client .Dispatch("Pyth on.TestServer")
for x in comobj:
print x

This works for me on Python 2.5 and pywin32 Build 210, but I don't know
whether clients in VB or Delphi are able to use this iterator.

-Carsten

I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.

Thanks loads.

-Larry
Apr 19 '07 #6
Larry Bates wrote:
Carsten Haese wrote:
[iterative acess to COM objects]
I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.
Presumably the magic of mark Hammond's wrapper classes providing
adaptation between Python iteration and COM enumerable collection
objects. win32all is *very* Pythonic.

Jim Hugunin, the author of IronPython (and of J[P]ython before that) has
commented that Microsoft users are frequently surprised by the small
amount of code required in IronPython to manipulate .NET objects.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Recent Ramblings http://holdenweb.blogspot.com

Apr 19 '07 #7
On Thu, 2007-04-19 at 12:49 -0400, Steve Holden wrote:
Larry Bates wrote:
Carsten Haese wrote:
[iterative acess to COM objects]
I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.
I'm glad, too.
Presumably the magic of mark Hammond's wrapper classes providing
adaptation between Python iteration and COM enumerable collection
objects. win32all is *very* Pythonic.
There is some magic, but it appears to be on the client side only. This
magic is what allows you to stick the win32com.client .Dispatcher object
into a for-loop.

If there were magic on the server side, it shouldn't be necessary to
declare that IID_IEnumVARIAN T is exposed, and it shouldn't be necessary
to implement the _NewEnum and Next methods; it should be enough to have
__iter__ present and let the magic take care of the rest.

It appears that the reason why my first completely uninformed guess
didn't work and my second somewhat less uninformed guess did work is
that there are two different enumeration protocols in the wonderfully
confusing world of Win32. I'm guessing that GetEnumerator/MoveNext is
the .NET enumeration protocol and IID_IEnumVARIAN T/Next is the COM
enumeration protocol.

-Carsten
Apr 19 '07 #8
Larry Bates wrote:
I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.
The documention Carsten Haese referenced earlier was for the .NET version
of VisualBasic, and shows how to use .NET's IEnumerate and IEnumerable
interfaces.

Steve Holden <st***@holdenwe b.comwrote:
>Presumably the magic of mark Hammond's wrapper classes providing
adaptation between Python iteration and COM enumerable collection
objects. win32all is *very* Pythonic.
Maybe Mark Hammond's win32all provides such a magic wrapper, but Cartsen
Haese's example didn't use it. Instead it provided it own implementation
of the COM IEnumVARIANT interface, the OLE Automation (ie. VisualBasic
6 compatable) way implementing iteratable objects.

Ross Ridge

--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rr****@csclub.u waterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/~rridge/
db //
Apr 19 '07 #9
Ross Ridge wrote:
Larry Bates wrote:
>I tested in VB and by golly it works! What is odd is that this looks
NOTHING like what we got from the docs earlier. No GetEnumerator
method, no MoveNext method. I'm glad it works, but I'm a little
puzzled as to why it works.

The documention Carsten Haese referenced earlier was for the .NET version
of VisualBasic, and shows how to use .NET's IEnumerate and IEnumerable
interfaces.

Steve Holden <st***@holdenwe b.comwrote:
>Presumably the magic of mark Hammond's wrapper classes providing
adaptation between Python iteration and COM enumerable collection
objects. win32all is *very* Pythonic.

Maybe Mark Hammond's win32all provides such a magic wrapper, but Cartsen
Haese's example didn't use it. Instead it provided it own implementation
of the COM IEnumVARIANT interface, the OLE Automation (ie. VisualBasic
6 compatable) way implementing iteratable objects.

Ross Ridge
So I saw when I read Carsten's reply to my post. Thanks. It's the
difference between COM and .NET (something I am currently having to come
to terms with myself, but strangely in C# rather than Python).

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Recent Ramblings http://holdenweb.blogspot.com

Apr 19 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
2211
by: Steven Bethard | last post by:
So, as I understand it, in Python 3000, zip will basically be replaced with izip, meaning that instead of returning a list, it will return an iterator. This is great for situations like: zip(*) where I want to receive tuples of (item1, item2, item3) from the iterables. But it doesn't work well for a situation like: zip(*tuple_iter)
10
3690
by: Andrew Dalke | last post by:
Is there an author index for the new version of the Python cookbook? As a contributor I got my comp version delivered today and my ego wanted some gratification. I couldn't find my entries. Andrew dalke@dalkescientific.com
1
1328
by: karye2004 | last post by:
Hi! I'm trying to access python objects from c++. It works once. Second time it hangs. Does someone have any clue or some example code or pointer? Thanks! /Karim Here are some python classes:
0
8983
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9359
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9310
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9236
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6072
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4592
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4863
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3298
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2774
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.