Method objects question

Ben Caradoc-Davies bmcd at es.co.nz
Tue Nov 23 19:14:13 EST 1999


On 23 Nov 1999 22:26:09 GMT, Donn Cave <donn at u.washington.edu> wrote:
>Well, it's possible, though perhaps not ideal if this were a cornerstone
>of your design.  You just have to add the function first to the class
>namespace, by whatever name is convenient;  then, you can add another
>reference to it in the instance by the name you want, hiding the original
>class attribute.  As long as the assignment that creates the second
>reference locates the function through the instance, you get a bound
>method.
>
>e.g., given class X and instance x,
>  x.bindme = x.bindme_new_7       # bound to instance x
>  x.bindme = X.bindme_new_7       # unbound
>
>So you're forced to use that class name space, but it's accessible
>and if you're worried about collisions, some system can presumably
>be invented to avoid them if you're desperate enough.

My suggestions are already enough of a hack, so I won't worry about collisions!
What you describe is quite a nice trick - binding an instance variable not to a
function object but to a method object. Now the method object is created when
the variable is bound, not when it is accessed. This certainly works around the
problem I described.

The only trap is that if the new function (bound in the class namespace) is
replaced, the binding in the instance must also be replaced, because the method
object still references the first new function.

Hey! Doesn't this solve the namespace collision problem? Now we can delete the
new function from the class namespace - it will live on as a reference in the
method object to which the instance variable is bound.

[Runs off and checks whether this works ...]
 
Yes! Now my problem is solved entirely with no adverse effects or strange
variables lying around.

Thanks, Donn!

Here's the example (compare with the start of this thread);

#################################################

class Demo:
  def __init__(self):
    self.i = 0

a = Demo()
b = Demo()

def incr_i(self): 
  self.i = self.i + 1

def decr_i(self): 
  self.i = self.i - 1

Demo.temp_foo = incr_i     # Here is Donn's technique.
a.foo = a.temp_foo         
del Demo.temp_foo          # Now the method has been safely constructed, we can
                           # restore the class Demo to it's original state.
Demo.temp_foo = decr_i     # And repeat ...
b.foo = b.temp_foo
del Demo.temp_foo

a.foo()                    # Just as desired!
b.foo()

print a.i                  # Correct results.
print b.i

#################################################

>I sure don't know how anything gets decided.  But I'm pretty sure I've
>used this the other way - that is, where the newly added function really
>is just a function, not a method.  I don't think that's terribly exotic,
>and it's possible due to the way this works.

And if instance functions were converted to methods, you would have to write
a wrapper for every ordinary function you wanted to store in an instance.

Thanks again.

-- 
Ben Caradoc-Davies <bmcd at es.co.nz>




More information about the Python-list mailing list