new.instancemethod questions

Brian Allen Vanderburg II BrianVanderburg2 at aim.com
Fri Jan 30 05:51:29 CET 2009


schickb at gmail.com wrote:
> On Jan 29, 7:38 pm, Mel <mwil... at the-wire.com> wrote:
>   
>> schickb wrote:
>>     
>>> I'd like to add bound functions to instances, and found the
>>> instancemethod function in the new module. A few questions:
>>>       
>>> 1. Why is instancemethod even needed? Its counter-intuitive (to me at
>>> least) that assigning a function to a class results in bound functions
>>> its instances, while assigning directly to instances does not create a
>>> bound function. So why doesn't assigning a function to an instance
>>> attribute result in a function bound to that instance?
>>>       
>> If I understand you correctly, rebinding to the instance would break code
>> like:
>>
>> myfakefile.write = sys.stdout.write
>>
>> where the intent would be to redirect any output through myfakefile straight
>> to sys.stdout.  The code for the sys.stdout.write function would never find
>> the attributes it needed in the instance of myfakefile.  To do this,
>> methods have to stay bound to their proper instances.
>>
>>     
>
> 1. I'm thinking about assigning free non-bound functions. Like:
>
> class A(object):
>    pass
>
> def func(self):
>    print repr(self)
>
> a = A()
> a.func = func  # Why doesn't this automatically create a bound
> function (aka method)?
>   
Actually I found out the implementation of why it doesn't after messing 
around some more.  If an attribute is found in the instance dictionary, 
even if it is a descriptor it's __get__ doesn't get called, only if it 
is found in the class dictionary of the class or base classes.  This 
makes it where you can store a function in the instance to be called 
later as a function for some useful purpose, for example two different 
instances of an object could use different sorting functions:

# sort functions are responsible for sorting which mutation is the least 
and most fit
def fitness1(v1, v2):
    # use one technique to determine which is more fit

def fitness2(v1, v2):
    # use another technique to determine which is more fit

... # more fitness functions

class Environment:
    def __init__(self, fitness, ...):
       self.fitness_func = fitness
       ...
    ...

# create environments, each one has different fitness function
a = Environment(fitness1)
b = Environment(fitness2)


Now when it is time to kill off the least fit of the genetic mutations, 
each environment can sort which is the least and most fit in different ways.
>
> 2. And what is the preferred way to do this if the "new" module and
> its instancemethod function are depreciated?
>
>   
Most of the code I see does this with a closure something like this:

def AddMethod(obj, func, name=None):
    if name is None:
       name = func.__name__

    def method(*args, **kwargs):
       return func(obj, *args, **kwargs)
    setattr(obj, name, method)

class MyClass(object):
    pass

def f1(self):
    print self

a = MyClass()
AddMethod(a, f1)

a.f1() # prints object a

You can also create a bound method and manually bind it to the 
instance.  This is easier

import types
a.f2 = types.MethodType(f1, a)

a.f2() # prints object a


These may work for most uses, but both have a problem that happens if 
you need to make a copy of the instance.  When you copy it, the copies 
'f1' will still call the function but using the old object

a.f1() # prints object a
b = copy.copy(a)
b.f1() # still prints a



Brian Vanderburg II



More information about the Python-list mailing list