Re: Why can't you pickle instancemethods?

2006-10-20 Thread mdsteele
Chris wrote:
> Why can pickle serialize references to functions, but not methods?
>
> Pickling a function serializes the function name, but pickling a
> staticmethod, classmethod, or instancemethod generates an error. In
> these cases, pickle knows the instance or class, and the method, so
> what's the problem? Pickle doesn't serialize code objects, so why can't
> it serialize the name as it does for functions? Is this one of those
> features that's feasible, but not useful, so no one's ever gotten
> around to implementing it?

I have often wondered this myself.  I'm convinced that it would in fact
be useful -- more than once I've written a program that has lots of
objects with function pointers, and where it was inconvenient that the
method pointers could not be pickled.  One compromise that I have used
before is to write a class such as:

class InstanceMethodSet(object):
def __init__(self,methods):
self.methods = set(methods)
def __getstate__(self):
return [(method.im_self, method.im_func.func_name)
for method in self.method]
def __setstate__(self,state):
self.methods = set(getattr(obj,name) for obj,name in state)

Obviously, this particular example is crude and not terribly robust,
but it seems to do the job -- it effectively lets you pickle a set of
instance method pointers.  I don't know of any reason why instance
methods (or class or static methods) couldn't be pickled directly,
unless perhaps there exists some kind of pathological corner case that
would create Badness?

-Matt

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting property functions

2006-10-20 Thread mdsteele
Dustan wrote:
> B isn't recognizing its inheritence of A's methods get_a and set_a
> during creation.
>
> Why am I doing this? For an object of type B, it makes more sense to
> reference the attribute 'b' than it does to reference the attribute
> 'a', even though they are the same, in terms of readability.
>
> Is there any way to make this work as intended?

Try this:

>>> class A(object):
... def __init__(self,a):
... self.__a = a
... def get_a(self): return self.__a
... def set_a(self,new_a): self.__a = new_a
... a = property(get_a,set_a)
...
>>> class B(A):
... b = property(A.get_a,A.set_a)
...
>>> bar = B(5)
>>> bar.a
5
>>> bar.b
5

The trouble is that get_a and set_a are attributes of the _class
object_ A.  Instances of A (and hence, instances of B) will see them,
but the class B will not, so you have to point to them explicitly with
A.get_a and A.set_a.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheriting property functions

2006-10-20 Thread mdsteele
Robert Kern wrote:
> Inheritance really doesn't work that way. The code in the class suite gets
> executed in its own namespace that doesn't know anything about inheritance. 
> The
> inheritance rules operate in attribute access on the class object later.

Right.  That was what I should have said, but it came out wrong when I
tried to say it.  (-:

-Matt

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why can't you pickle instancemethods?

2006-11-10 Thread mdsteele
Steven Bethard wrote:
> Here's the recipe I use::
>
>  [...]
>
> There may be some special cases where this fails, but I haven't run into
> them yet.

Wow, that's a really nice recipe; I didn't even know about the copy_reg
module.  I'll have to start using that.

I did notice one failure mode, however--it doesn't work with methods
named __foo because im_func.__name__ contains the *unmangled* version
of the function name, so when you try to unpickle the method, the try
statement never succeeds and you get an UnboundLocalError on func.

The good news is that I think it can be fixed by mangling the name
manually in _pickle_method(), like so:

def _pickle_method(method):
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
if func_name.startswith('__') and not func_name.endswith('__'):
cls_name = cls.__name__.lstrip('_')
if cls_name: func_name = '_' + cls_name + func_name
return _unpickle_method, (func_name, obj, cls)

-- 
http://mail.python.org/mailman/listinfo/python-list


Strange __future__ behavior in Python 2.5

2006-09-23 Thread mdsteele
My understanding of the __future__ statement is that you may say
something like:

from __future__ import foo, bar

to enable more than one feature.  However, this does not seem to be
working properly in 2.5; it behaves as expected when typed into the
interactive interpreter, but not when it is in a module.  When I try to
import the following module:

from __future__ import with_statement, division, absolute_import
def bar():
print 5/3
with open('asdf') as f:
for line in f: print line.strip()

I get a warning that 'with' will soon be a reserved keyword, and a
SyntaxError on the line with the with statement, so obviously, the
__future__ statement is not working.  When I change the first line to:

from __future__ import with_statement
from __future__ import division,absolute_import

then the with statement works fine.  However, the true division also
works fine, so apparently making multiple __future__ imports on one
line works for division, but not for with_statement.

Is this a bug, or am I misunderstanding something?  I'm using the final
release of Python 2.5 (r25:51918, Sep 19 2006, 08:49:13) on Mac OS X.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Looping over a list question

2006-10-03 Thread mdsteele

[EMAIL PROTECTED] wrote:
> I found myself writing:
>
> for f in [i for i in datafiles if '.txt' in i]:
> print 'Processing datafile %s' % f
>
> but I was wishing that I could have instead written:
>
> for f in in datafiles if '.txt' in f:
> print 'Processing datafile %s' % f
>
> Has there ever been a proposal for this? Just wondering ...
>
> Stephen Boulet


Yes, there has:
http://groups.google.ca/group/comp.lang.python/browse_thread/thread/905313cf066c2d18/e6af21b68309415f

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there an easier way to express this list slicing?

2006-11-30 Thread mdsteele
John Henry wrote:
> Can I say something to the effect of:
>
> (a,b,c[0:2],d[0:5])=a_list# Obviously this won't work

Your best bet is probably:

x = [...some list...]
a,b,c,d = x[:1],x[1:2],x[2:5],x[5:]

> I am asking this because I have a section of code that contains *lots*
> of things like this.  It makes the code very unreadable.

Of course, if you're always slicing up lists the same way (say, into
1,1,3,5 element sections) then you could improve readability by writing
a function that takes the list and returns a tuple of the pieces, such
as:

def slice_list(x):
return x[:1],x[1:2],x[2:5],x[5:]

a,b,c,d = slice_list(first_list)
e,f,g,h = slice_list(second_list)

-Matt

-- 
http://mail.python.org/mailman/listinfo/python-list