cPickle and __getattr__

C

Chris Curvey

Hi all,

I have this program

class Company:
def __init__(self, revenues, costs):
self.revenues = revenues
self.costs = costs

def __getattr__(self, name):
if name == 'profits':
return self.revenues - self.costs

c = Company(100, 75)
print c.revenues
print c.costs
print c.profits

import cPickle
print cPickle.dumps(c)

Everything works fine up until the last line. If I remove the
__getattr__ function, then everything works (except "print c.profits").
What is the cPickle class trying to get to that is causing my
__getattr__ function to be called?

-Chris
 
J

Jp Calderone

Chris said:
Hi all,

I have this program

class Company:
def __init__(self, revenues, costs):
self.revenues = revenues
self.costs = costs

def __getattr__(self, name):
if name == 'profits':
return self.revenues - self.costs

c = Company(100, 75)
print c.revenues
print c.costs
print c.profits

import cPickle
print cPickle.dumps(c)

Everything works fine up until the last line. If I remove the
__getattr__ function, then everything works (except "print c.profits").
What is the cPickle class trying to get to that is causing my
__getattr__ function to be called?

Potentially lots of things. But the problem isn't that cPickle is
calling __getattr__, exactly. The problem is that your __getattr__
isn't properly signalling non-existent attributes. You should raise
AttributeError instead of implicitly returning None for which there is
no attribute. Adding "raise AttributeError(name)" to the end of the
definition unbreaks it enough to let pickle work.

Jp
 
P

Paul Morrow

Chris said:
Hi all,

I have this program

class Company:
def __init__(self, revenues, costs):
self.revenues = revenues
self.costs = costs

def __getattr__(self, name):
if name == 'profits':
return self.revenues - self.costs

c = Company(100, 75)
print c.revenues
print c.costs
print c.profits

import cPickle
print cPickle.dumps(c)

Everything works fine up until the last line. If I remove the
__getattr__ function, then everything works (except "print c.profits").
What is the cPickle class trying to get to that is causing my
__getattr__ function to be called?

-Chris

When you use __getattr__, you should always raise an attribute error for
names that you don't handle.

def __getattr__(self, name):
if name == 'profits':
return self.revenues - self.costs
else:
raise AttributeError, name

Paul
 
C

Chris Curvey

Potentially lots of things. But the problem isn't that cPickle is
calling __getattr__, exactly. The problem is that your __getattr__
isn't properly signalling non-existent attributes. You should raise
AttributeError instead of implicitly returning None for which there is
no attribute. Adding "raise AttributeError(name)" to the end of the
definition unbreaks it enough to let pickle work.

Ah, that's it. Many thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top