changing __getattr__ dynamically

D

Dan Bentley

class foo(object):
def __getattr__(self, name):
return 42

def e(self, name):
return 2.7

bar = foo()
print bar.baz
bar.__getattr__ = e
print bar.baz

I'd expect this to print:
42
2.7

But instead it prints:
42
42

Is there a way to change the actual __getattr__ used at runtime?

-D"python 2.3.3 on Mac OS X 10.3.4"an
 
S

Satchidanand Haridas

Dan said:
class foo(object):
def __getattr__(self, name):
return 42

def e(self, name):
return 2.7

bar = foo()
print bar.baz
bar.__getattr__ = e
print bar.baz

I'd expect this to print:
42
2.7

But instead it prints:
42
42

Is there a way to change the actual __getattr__ used at runtime?

-D"python 2.3.3 on Mac OS X 10.3.4"an

The following code will do so:

<code>

class foo(object):

def __getattr__(self, name):
if 'attrFunc' in self.__dict__:
return self.__dict__['attrFunc'](name)
else:
return 42

def __setattr__(self,name,value):
self.__dict__[name] = value

def e(self,name):
return 27

bar = foo()
print bar.baz
bar.attrFunc = bar.e
print bar.baz

</code>

Regards,
Satchit

----
Satchidanand Haridas (sharidas at zeomega dot com)

ZeOmega (www.zeomega.com)
Open Minds' Open Solutions

#20,Rajalakshmi Plaza,
South End Road,
Basavanagudi,
Bangalore-560 004, India
 
P

Peter Otten

Dan said:
Is there a way to change the actual __getattr__ used at runtime?

Special methods are always looked up in the class, any changes must
therefore be made in the class and will affect all instances.
.... def __getattr__(self, name):
.... return 42
........ return 2.7
....2.7

Peter
 
P

Peter Otten

Dan said:
class foo(object):
def __getattr__(self, name):
return 42

def e(self, name):
return 2.7

bar = foo()
print bar.baz
bar.__getattr__ = e
print bar.baz

I'd expect this to print:
42
2.7

But instead it prints:
42
42

Is there a way to change the actual __getattr__ used at runtime?

One more note - the above wouldn't work for "normal" methods, too:
.... def e(self): return "in class"
........ return "in instance"
....Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: ee() takes exactly 1 argument (0 given)

I.e. if you assign a function to an instance attribute, self will not be
passed implicitely. Instead
'in class'

will achieve the desired specialization for the modified foo instance while
preserving the standard behaviour.

Peter
 

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

Staff online

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top