new.instancemethod questions

S

schickb

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?

2. The 2.6 docs say the new module is depreciated and refers to the
types module instead. But I haven't found a way to create bound
functions using the types module. Am I just missing something?

Thanks,
-Brad
 
M

Mel

schickb said:
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.

Mel.
 
S

schickb

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)?


2. And what is the preferred way to do this if the "new" module and
its instancemethod function are depreciated?


-Brad
 
B

Brian Allen Vanderburg II

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
 
S

schickb

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

Ah thanks, that is what I was looking for. I missed that because
following types.MethodType in the docs is:

types.UnboundMethodType
An alternate name for MethodType

Which made me think it was a type for UnboundMethods (aka functions).
This:
clears it up for me, but the docs are rather confusing.

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

Ugh, that is a problem. I guess that means pickling won't work
either....

Nope, "TypeError: can't pickle instancemethod objects". So does these
mean there is no way to create a method on an instance at runtime that
behaves just like a method that originated from the instance's class?

-Brad
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top