0

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

3
  • Since the subclass inherits the superclass function, why are you doing this? What's the point? Commented Nov 19, 2009 at 20:39
  • Alex has pointed out, that the original unbound method Base.payload cannot be converted to another classes member function with the same name. Even with inherited classes. I am currently setting up a tree iteration. Looks like I should use a Visitor/Multimethod approach or have IDs per payload handler with a dispatcher per node. It will be used to store XML output from a Sax parser- Commented Nov 19, 2009 at 21:06
  • Use Visitor whenever possible. Avoid magic. Commented Nov 19, 2009 at 21:40

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your clarification. The name of the passed unbound function is indeed the only link amongst Base and Drvd implementations.
1

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!

Comments

0

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.]

1 Comment

I am trying to reduce coding effort on tarversing a treelike structure of nodes compared to a visitor-pattern or multimethod approach. It seems to become a hack though on bending pythons underlying method signatures.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.