Reputation: 1
In following example I am trying to bind a method object via types.MethodType(...). It does not seem to work. Any suggestions? Thanks in advance.
import types
class Base:
def payload(self, *args):
print "Base:payload"
class Drvd(Base):
def iter(self, func):
derived_func = types.MethodType(func, self, Drvd) # bind
print "drvd_func:", derived_func
derived_func() # result: calls Base:payload
# expected:calls Drvd:payload; why???
def payload(self, *args):
print "Drvd:payload"
derived = Drvd()
base_func = Base.payload
print "base_func:", base_func
derived.iter(base_func) # pass unbound method object
The output shows:
base_func: <unbound method Base.payload>
drvd_func: <bound method Drvd.payload of <main.Drvd instance at 0x00B51648>>
Base:payload
Upvotes: 0
Views: 2683
Reputation: 881705
You're specifically requesting the use of the underlying function (im_func
) of Base.payload
, with a fake im_class
of Drvd
. Add after the existing print
in iter
:
print "w/class:", derived_func.im_class
print "w/func:", derived_func.im_func
and you'll see the total output as:
$ python bou.py
base_func: <unbound method Base.payload>
drvd_func: <bound method Drvd.payload of <__main__.Drvd instance at 0x24a918>>
w/class: __main__.Drvd
w/func: <unbound method Base.payload>
Base:payload
i.e., as you've asked, the underlying code being used is indeed Base.payload
-- which is also what you observe in the call.
From Base.payload
there is no direct way to get to Drvd.payload
except by getting the name and using it to do a getattr
on self
(a Drvd
instance), or equivalent.
Upvotes: 2
Reputation: 10967
I don't really understand what you're trying to do - but to me it's working as I'd expect. You are binding Base.payload to Drvd - from your print out you can see it is binding correctly to your Drvd instance. I'm not sure why you are then expecting it to call Drvd.payload - you have bound the function object Base.payload. It is always going to be that function.
[edit: just to add - it might be helpful if you say what your trying to do in general terms. What you're doing at the moment doesn't make much sense - Python has inheritence so if you want to override the payload method you can just do it - you don't need to do any manual binding.]
Upvotes: 0
Reputation: 45324
Because you passed Base's payload (not Drvd's) to iter!
Hint:
print "%s: Base:payload"%repr(self)
Kudos for creating an accursed chimera of a thing, though!
Upvotes: 1