Winter Madness - Passing Python objects as Strings

Hendrik van Rooyen mail at microcorp.co.za
Sat Jun 6 05:37:50 EDT 2009


"Scott David Daniels" <S..el at Acm.Org> wrote:

> I can think of use cases for can, and from that use an alternate
> construct.   The use case is passing a reference out over a wire
> (TCP port?) that will be used later.

This will work, provided the thing is still alive and in the same place
when the can eventually finds its way back and gets uncanned.
As it is now, no attempt has been made to handle refcounting
issues.

> Sub cases:
> (1) Handing work over the wire along with a callback to invoke
>      with the results.
> (2) Handing work over the wire along with a progress callback.
> (3) Handing work over the wire along with a pair of result functions,
>      where the choice of functions is made on the far side of the wire.
> 
> The "can" can be used to send the function(s) out.
> Alternatively, for use case 1:
> 
>      class Holder(object):
>          def __init__(self):
>              self.key = 0
>              self.holds = {}
>          def handle(self, something):
>              key = str(self.key) # may need to lock w/ next for threads
>              self.key += 1
>              self.holds[key] = something
>              return key
>          def use(self, handle):
>              return self.holds.pop(handle)

This is nice - you are making a simple index.

Dammit! why did I not think of something like this -
It keeps it all in Python, without a C extension.
In my case I would need a global so that I would
know where to look it up in, but that is a non issue
as it can be made at startup.  

I really should keep the maxim in mind:

There is no problem in computer science that can
not be solved by means of the introduction of another
layer of indirection.

:-)

Thanks for this post Scott - it has helped to straighten
out my one track minded thinking - I got hung up on the 
idea of passing the reference, to the extent that I expended
what was for me heroic effort to get it across.

What causes me real chagrin is that I am already keeping
a list of queues - the active queue list that keeps the list
of output queues for the various clients that have connected.
And I am too dim witted to think of a dict...

> 
> Otherwise a simple dictionary with separate removal may be needed.
> If you might abandon an element w/o using it, use a weakref dictionary,
> but then you need a scheme to keep the thing alive long enough
> for needed operations (as you also need with a can).

In my use case the queue would have stayed alive because
the thread that created it would have kept it going until
it was no longer needed, as would the reference created
by the binding of the local name in the thread.

> 
> In use case 1, the dictionary becomes that holding point.
> The counter-as-key idea allows you to keep separate references
> to the same thing, so the reference is held for precisely as long
> as needed.  It (counter-as-key) beats the str(id(obj)) of can
> because it tracks the actual object, not simply the id that can
> be reused.

The can just looks like str(id(obj)) - at the C level, it
actually comes from the PyObject *, gets stringified,
and the uncan returns the original PyObject *. So
if I understand it correctly, after the uncanning, it 
__is__ the original object. (if it is still there)

As I said above, I have paid no attention to refcounting
issues, - it really needs someone knowledgeable to
work over my C code, as this was my first venture into
the wonderful world of extending python.

But it hardly seems worth while now...

- Hendrik





More information about the Python-list mailing list