Attribute monitoring in a class

  • Thread starter Joel Andres Granados
  • Start date
J

Joel Andres Granados

Hi list:

I have googled quite a bit on this matter and I can't seem to find what
I need (I think Im just looking where I'm not suppose to :). I'm
working with code that is not of my authorship and there is a class
attribute that is changes by directly referencing it (object.attr =
value) instead of using a getter/setter (object.setAttr(Value) )
function. The thing is that I have no idea when the change occurs and I
would REALLY like to find out.
So here comes my question .....
Is there a function construct inside a python class that is
automatically called when an attr is changed????
Like for example

/class Class:
def __init__();
self.attr = "whatever"

def __attrChangeFunction__():
print "It has changed"

obj = Class()
obj.attr = "other whatever"

*Output:*
It has changed

/
Thanks for the help.
Regards/
/
 
B

Bruno Desthuilliers

Joel Andres Granados a écrit :
Hi list:

I have googled quite a bit on this matter and I can't seem to find what
I need (I think Im just looking where I'm not suppose to :). I'm
working with code that is not of my authorship and there is a class
attribute that is changes by directly referencing it (object.attr =
value) instead of using a getter/setter (object.setAttr(Value) )

Which is the right thing to do in Python (I mean : *not* using
Java-style getters/setters).
function. The thing is that I have no idea when the change occurs and I
would REALLY like to find out.
So here comes my question .....
Is there a function construct inside a python class that is
automatically called when an attr is changed????

yes : object.__setattr__(self, name, value)

# example:
class Class(object):
def __init__();
self.attr = "whatever"

def __setattr__(self, name, value):
object.__setattr__(self, name, value)
if name == 'attr':
print "It has changed"
# you can also print the call frame,
# or set a 'hard' breakpoint here...

obj = Class()
obj.attr = "other whatever"

*Output:*
It has changed


Or you might turn attr into a property:

class Class(object):
def __init__();
self.attr = "whatever"

@apply
def attr():
def fset(self, value):
self._attr = value
print "It has changed"
def fget(self):
return self._attr
return property(**locals())

But unless you have other needs than simple tracing/debugging, it's
probably overkill.

HTH
 
L

Laurent Pointal

Joel Andres Granados a écrit :
Hi list:

I have googled quite a bit on this matter and I can't seem to find what
I need (I think Im just looking where I'm not suppose to :). I'm
working with code that is not of my authorship and there is a class
attribute that is changes by directly referencing it (object.attr =
value) instead of using a getter/setter (object.setAttr(Value) )
function. The thing is that I have no idea when the change occurs and I
would REALLY like to find out.
So here comes my question .....
Is there a function construct inside a python class that is
automatically called when an attr is changed????
Like for example

/class Class:
def __init__();
self.attr = "whatever"

def __attrChangeFunction__():
print "It has changed"

Use a property. Extract from Python 2.3 docs:
"""
property( [fget[, fset[, fdel[, doc]]]])
Return a property attribute for new-style classes (classes that
derive from object).

fget is a function for getting an attribute value, likewise fset is
a function for setting, and fdel a function for del'ing, an attribute.
Typical use is to define a managed attribute x:

class C(object):
def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "I'm the 'x' property.")

New in version 2.2.
"""
obj = Class()
obj.attr = "other whatever"

*Output:*
It has changed

/
Thanks for the help.
Regards/
/

A+

Laurent.
 
J

Joel Andres Granados

Bruno said:
Joel Andres Granados a écrit :


Which is the right thing to do in Python (I mean : *not* using
Java-style getters/setters).



yes : object.__setattr__(self, name, value)

# example:
class Class(object):
def __init__();
self.attr = "whatever"

def __setattr__(self, name, value):
object.__setattr__(self, name, value)
if name == 'attr':
print "It has changed"
# you can also print the call frame,
# or set a 'hard' breakpoint here...

obj = Class()
obj.attr = "other whatever"

*Output:*
It has changed

I used this ^^^^^^^^^^^^^^^ one. Thank for the help.
Works like a charm.
Regards
 
B

Bruno Desthuilliers

Gabriel Genellina a écrit :
En Wed, 14 Mar 2007 10:01:54 -0300, Joel Andres Granados


The problem with __setattr__ is that it slows down significantly *all*
attributes.
Yours is the typical case when it's good to switch from using simple
attributes to using properties.

If this has to become a feature of the class, yes, indeed. If it's just
a temporary hack for debugging, the using the __getattr__ hook is
quicker and less intrusive.
 

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

No members online now.

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top