Reusing object methods?

I

Ivan Voras

Can this be done: (this example doesn't work)

----
class A:

def a_lengthy_method(self, params):
# do some work depending only on data in self and params

class B:

def __init__(self):
self.a_lengthy_method = A.a_lengthy_method
# I know that data in "self" of class B object is compatible
# with that of class A object
 
L

Leif K-Brooks

Ivan said:
I want to 'reuse' the same method from class A in class B, and without
introducing a common ancestor for both of them - is this possible in an
elegant, straightforward way?
.... def foo(self):
.... print "Hello, %s!" % self.__class__.__name__
........ def __init__(self):
.... self.foo = new.instancemethod(A.foo.im_func, self, B)
....Hello, B!
 
P

Peter Otten

Ivan said:
I want to 'reuse' the same method from class A in class B, and without
introducing a common ancestor for both of them - is this possible in an
elegant, straightforward way?

Straightforward, if not elegant:
.... print self, params
........ method = method
........ method = method
....
Peter
 
B

Bengt Richter

Can this be done: (this example doesn't work)

----
class A:

def a_lengthy_method(self, params):
# do some work depending only on data in self and params

class B:

def __init__(self):
self.a_lengthy_method = A.a_lengthy_method
# I know that data in "self" of class B object is compatible
# with that of class A object
----

I want to 'reuse' the same method from class A in class B, and without
introducing a common ancestor for both of them - is this possible in an
elegant, straightforward way?

Your design intent is not quite clear to me, since you are trying to
capture the A method from B's instance initialization. If it is to be
a method of B, why not put the code in the class body of B instead
of in B.__init__, whose concern is B instances, not the B class (at least normally).
OTOH, if you really want an "instance-method" as an attribute of a B instance, see
class B below. Such a method is not shared by different instances, though the
example here doesn't demonstrate that, since they would all be clone instance-methods.
The C and D examples provide a shared method to their instances.

Here are some ways to do what you might be wanting to do ;-)
... def a_lengthy(self, params): return self, params
... ... def __init__(self):
... self.a_lengthy = A.a_lengthy.im_func.__get__(self, type(self))
... ... a_lengthy = A.a_lengthy.im_func
... ... a_lengthy = A.__dict__['a_lengthy']
... {}

Note that class B borrows the A method and makes an "instance-method" -- i.e.,
a bound method bound to the instance and set as an attribute of that instance
(which is why it shows up in vars(b)).

This mechanism could make customized instance-methods for different instances,
if you wanted to, since the class B is not modified by making variations.

A method is just a class variable whose value is a function, until it is
accessed as an attribute of either the class or an instance. What makes
it a method is the attribute-retrieval mechanism. So what you want to do
is possible, but A.a_lengthy_method is not the function, it is an unbound
method (because it was retrieved as an attribute of the class as opposed
to via an instance. For an ordinary method, you can get the function via
the im_func attribute, but if you want to borrow something trickier, you
may want to try the way class D does it.

For new-style classes, you will run across some differences.

Regards,
Bengt Richter
 
J

Joal Heagney

Axel said:
Hello!

Why not:




?

Lg,
AXEL.

As a rough guess, I think the original poster was wondering how to
include *one* specific method from class A into B, without including all
the methods of A. Jp Calderone's suggestion of defining a special Mixin
class seems to be the cleanest implementation.

E.g.

class MyMixin:
""" Defines only a single method. It may be a debug call, or
a replacement for the classes' string representation. Etc. """
def a_lengthy_method(self,params):
# do some work

class A(MyMixin):
def other_lengthy_procedures(self, params):
pass

class B(MyMixin):
pass

The advantage of this is that you can define a normal inheritance tree
for a variety of classes, and then specifically override a single (or
group) of methods by placing the MyMixin class at the front of the
inheritance call. (The book "Programming Python" uses this a LOT in the
Tkinter section.)

E.g.

class C:
def well_now_what_do_we_do(self):
# stuff
def a_lengthy_method(self,params):
# This does the wrong stuff.

class D(MyMixin, C):
def __init__(self):
# blahblahblah

Now class D has the "correct" a_lengthy_method, inherited from MyMixin,
as well as all the other methods from class C, and the methods defined
in it's own class statement.

Joal
 
M

Michele Simionato

If you need just a single method once, don't use a mixin; just do
B.meth = A.meth.im_func. Do not underestimate the burden of
mixins on people reading your code (at least, for me it is burden,
since I have to draw the inheritance tree in my mind, look at which
methods are involved, wonder about the resolution order etc.)


Michele Simionato
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top