setattr getattr confusion

D

Donn Ingle

Hi,
Here's some code, it's broken:


class Key( object ):
def __init__(self):
self.props = KeyProps()
def __getattr__(self, v):
return getattr( self.props,v )
def __setattr__(self,var,val):
object.__setattr__(self.props,var,val)

class KeyProps(object):
def __init__(self):
self.x="NOT SET YET"
k1=Key()

It does not run because of the recursion that happens, but I don't know how
to lay this out.

I am trying to set the x value within props within Key:
k1.x="DAMN"
print k1.x

It seems to work, but it's really making a new 'x' in k1.
print k1.props.x
Shows "NOT SET YET", thus proving it failed to set x here.

I want to change k1.props.x by k1.x="something new" -- can this be done?

\d
 
J

James Stroud

Donn said:
Hi,
Here's some code, it's broken:


class Key( object ):
def __init__(self):
self.props = KeyProps()
def __getattr__(self, v):
return getattr( self.props,v )
def __setattr__(self,var,val):
object.__setattr__(self.props,var,val)

class KeyProps(object):
def __init__(self):
self.x="NOT SET YET"
k1=Key()

It does not run because of the recursion that happens, but I don't know how
to lay this out.

I am trying to set the x value within props within Key:
k1.x="DAMN"
print k1.x

It seems to work, but it's really making a new 'x' in k1.
print k1.props.x
Shows "NOT SET YET", thus proving it failed to set x here.

I want to change k1.props.x by k1.x="something new" -- can this be done?

\d

You will want to study the attribute proxy recipe:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/510402

Also, its not obvious how what you seem to be describing is different from:

class Key(object):
def __init__(self):
self.x = 'NOT SET YET'
self.props = self

e.g.

py> class Key(object):
.... def __init__(self):
.... self.x = 'NOT SET YET'
.... self.props = self
....
py> k = Key()
py> k.props.x
'NOT SET YET'
py> k.x
'NOT SET YET'
py> k.x = "DAMN"
py> k.x
'DAMN'
py> k.props.x
'DAMN'

So you might want to describe your use-case.



James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com
 
D

Donn Ingle

So you might want to describe your use-case.
Um.. I wanted an object with Key to hold other data. I wanted a way to set
that *other* data within Key without having to specify the "object
in-between" everytime.

k1.x = "ni!"

should perform:
k1.props.x = "ni!"

and
print k1.x
should perform:
print k1.props.x


I'll go look at your link. Thanks.

\d
 
C

Carl Banks

Hi,
Here's some code, it's broken:

class Key( object ):
def __init__(self):
self.props = KeyProps()
def __getattr__(self, v):
return getattr( self.props,v )
def __setattr__(self,var,val):
object.__setattr__(self.props,var,val)

If you define __setattr__ you can't initialize attributes the ordinary
way. Instead, use self.__dict__. (Once it's initialized, you can
refer to it in the ordinary way.) So do it like this:

class Key(object):
def __init__self):
self.__dict__['props'] = KeyProps()
def __getattr__(self,var):
return getattr(self.props,var)
def __setattr__(self,var,val):
setattr(self.props,var,val)


Carl Banks
 
S

Steven D'Aprano

Um.. I wanted an object with Key to hold other data. I wanted a way to
set that *other* data within Key without having to specify the "object
in-between" everytime.

That's called "automatic delegation".
 
D

Donn Ingle

class Key(object):
def __init__self):
self.__dict__['props'] = KeyProps()
Okay - that's weird. Is there another way to spin this?
def __setattr__(self,var,val):
setattr(self.props,var,val)
Perhaps by changing this one?

\d
 
B

Bruno Desthuilliers

Donn Ingle a écrit :
class Key(object):
def __init__self):
self.__dict__['props'] = KeyProps()

Okay - that's weird.

No, that's coherent. The default behavior (I mean, when there's no
descriptor involved etc) of __setattr__ is to store attributes in
instance.__dict__. So as long a you override __setattr__, you have to
take care of this by yourself.
Is there another way to spin this?


Perhaps by changing this one?

If you know by advance which names should live in your object and/or
which should belong to the KeyProps instance, then you can check and
dispatch, ie:


class Key(object):
# names that must not be delegated to instance.props
_mynames = ['props', 'foo', 'bar']

def __setattr__(self, name, value):
if name in self._mynames:
object.__setattr__(self, name, value)
else:
setattr(self.props, name, value)
 
D

Donn Ingle

Thanks Bruno, I had to keep coding, so I used the long form
[Object.subobject.property = blah] anyway. It's long-winded, but
unambiguous.

\d
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top