3

i've got a problem with python: I want to assign a method to an object form another class, but in this method use its own attributes. Since i have many container with different use methods in my project (not in that example) i dont want to use inheritance, thad would force me to create a custom class for each instance.

class container():
    def __init__(self):
        self.info = "undefiend info attribute"

    def use(self):
        print self.info


class tree():
    def __init__(self):

        # create container instance
        b = container()

        # change b's info attribute
        b.info = "b's info attribute"

        # bound method test is set as use of b and in this case unbound, i think
        b.use = self.test

        # should read b's info attribute and print it
        # should output: test: b's info attribute but test is bound in some way to the tree object
        print b.use()

    # bound method test
    def test(self):
        return "test: "+self.info


if __name__ == "__main__":
    b = tree()

Thank you very much for reading this, and perhaps helping me! :)

4 Answers 4

2

Here you go. You should know that self.test is already bound since by the time you are in __init__ the instance has already been created and its methods are bound. Therefore you must access the unbound member by using the im_func member, and binding it with MethodType.

import types

class container():
    def __init__(self):
        self.info = "undefiend info attribute"

    def use(self):
        print self.info


class tree():
    def __init__(self):

        # create container instance
        b = container()

        # change b's info attribute
        b.info = "b's info attribute"

        # bound method test is set as use of b and in this case unbound, i think
        b.use = types.MethodType(self.test.im_func, b, b.__class__)

        # should read b's info attribute and print it
        # should output: test: b's info attribute but test is bound in some way to the tree object
        print b.use()

    # bound method test
    def test(self):
        return "test: "+self.info


if __name__ == "__main__":
    b = tree()
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, i've to learn some more about types and MethodType. But your solution works very well!
@blackforestcowboy: This knowledge is black magic so I wouldn't expect you to know about it. It is not documented anywhere last time I checked. I discovered it myself when I was trying to make a plugin system, and all the self-described Python experts told me it couldn't be done and kept questioning me instead of giving answers.
@Unknown: Yea black magic I like! ;) I just googled around for the types.MethodType packacke and could bearly find information about it. I'm also trying to write some kind of PluginSystem, so inheritence would be much more code to write. Thank you very much again.
1

Looks like you are trying to use inheritance? The tree inherits from the container?

Comments

1

Use tree.test instead of self.test. The method attributes of an instance are bound to that instance.

Comments

1

Do not move methods around dynamically.

Just Use Delegation. Avoid Magic.

Pass the "Tree" object to the Container. It saves trying to move methods around.

class Container( object ):
    def use( self, context ):
        print context.info
        context.test()

class Tree( object ):
    def __init__( self, theContainerToUse ):
        b= theContinerToUse( self )
        print b.use()
    def test( self ):
        print "test"+self.info

2 Comments

@S.Lott Thank you for your solution, at the moment i dont get how that helps me, but i'm at work at the moment, so i sadly have to deal with java... But i sure will think about it after work! Thank you!
@S.Lott No no, its a python question, not java!! this question is regarding a private project what i program in python, BUT at work, i have to work with java, there is no question about that. Sorry for the confusion! This is defenitely a python question!

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.