FAQ
I'm a little new to the language, so please excuse me if I'm missing
something obvious. I've run into (what looks like) a strange
inconsistency in the language. Anyway, I have a setup where I
initialize a class object within another class, and then have to
overload one of the new object's functions:

BEGIN SAMPLE CODE:

class A:
def __init__(self):
pass

def setFunction(self, fromFunc, toFunc):
fromFunc = toFunc

def myPrint(self):
print 'Old'


class myClass:
def __init__(self):
a = A()

#a.setFunction(a.myPrint, self.newPrint)
a.myPrint = self.newPrint

a.myPrint()

def newPrint(self):
print 'New'


b = myClass()


END SAMPLE CODE

The code above works fine, and prints out 'New' like it should.
However, when I try to use the commented line (a.setFunction...)
instead of (a.myPrint = self.newPrint), the a.myPrint function is not
getting overloaded and still prints out 'Old'. It seems to me that
since I'm passing both method instance objects to a.setFunction(),
there should be no problem overloading them. Is there a way I can do
this with a function call? It's important for this system to have a
generic method for overloading functions...

Search Discussions

  • Jack Diederich at Jan 8, 2003 at 9:05 pm

    On Wed, Jan 08, 2003 at 12:34:01PM -0800, Sean wrote:
    I'm a little new to the language, so please excuse me if I'm missing
    something obvious. I've run into (what looks like) a strange
    inconsistency in the language. Anyway, I have a setup where I
    initialize a class object within another class, and then have to
    overload one of the new object's functions:

    BEGIN SAMPLE CODE:

    class A:
    def __init__(self):
    pass

    def setFunction(self, fromFunc, toFunc):
    fromFunc = toFunc

    def myPrint(self):
    print 'Old'


    class myClass:
    def __init__(self):
    a = A()

    #a.setFunction(a.myPrint, self.newPrint)
    a.myPrint = self.newPrint

    a.myPrint()

    def newPrint(self):
    print 'New'


    b = myClass()


    END SAMPLE CODE

    The code above works fine, and prints out 'New' like it should.
    However, when I try to use the commented line (a.setFunction...)
    instead of (a.myPrint = self.newPrint), the a.myPrint function is not
    getting overloaded and still prints out 'Old'. It seems to me that
    since I'm passing both method instance objects to a.setFunction(),
    there should be no problem overloading them. Is there a way I can do
    this with a function call? It's important for this system to have a
    generic method for overloading functions...

    The effect you are going for is regular inheritence,

    class A:
    def __init__(self):
    self.myPrint()

    def myPrint(self):
    print 'Old'

    class myClass(A):
    def __init__(self):
    A.__init__(self)

    def myPrint(self):
    print 'New'

    b = myClass()
    g = A()

    will print
    New
    Old

    -jackdied
  • Jeff Epler at Jan 8, 2003 at 9:15 pm
    You don't have to write anything so complicated to see that Python
    doesn't work the way you want it to work. For instance,

    def add_one(x):
    x = x + 1

    x = 1
    add_one(x)
    print x # prints 1, not 2

    If you really want to write 'setFunction', you'll have to do it
    something like this:

    def setFunction(self, funcname, tofunc):
    setattr(self, funcname, tofunc)
    # OR
    # self.__dict__[funame] = tofunc

    and call it like this:
    a.setFunction('myPrint', self.newPrint)

    This is really a very odd thing to do, though...

    Jeff
  • Peter Hansen at Jan 8, 2003 at 9:40 pm

    Sean wrote:
    Anyway, I have a setup where I
    initialize a class object within another class, and then have to
    overload one of the new object's functions:

    class A:
    def __init__(self):
    pass

    def setFunction(self, fromFunc, toFunc):
    fromFunc = toFunc
    This line can only rebind the *local* variable called "fromFunc"
    away from the value that was passed in, to the value bound to the
    local variable called "toFunc". It has no effect whatsoever
    on the attributes of any instance of A, since the variables are
    entirely local to the function...

    Also, you are not *overloading* member functions. That's a term
    from other languages which refers to the ability to create
    multiple methods *with the same name* but with different type
    signatures, and the compiler choses which one to call based on
    the types of the arguments provided. Since Python is dynamically
    typed, it does not support this concept.

    I would say that you are perhaps *overriding* the methods, but
    even that term is already used to refer to the case where a
    child class replaces the definition of a method in the parent
    class with its own version, to extend the functionality.

    Perhaps we should just refer to *replacing* or even, in Python
    fashion, *rebinding* member functions (which I would call
    "methods", usually).

    As for how you do it... use references to the *class* names
    and not the instances:

    in the myClass __init__ method, do this:

    a = A()
    a.setFunction('myPrint', myClass.newPrint)

    and in the setFunction method, do this:

    setattr(self.__class__, fromFunc, toFunc)

    Or did you really mean to replace the function in *only* the
    one instance of the A class? That takes a different approach,
    which I can't recall off the top of my head.... using bound
    methods?

    -Peter
  • Laotseu at Jan 9, 2003 at 4:24 am

    Sean wrote:
    I'm a little new to the language, so please excuse me if I'm missing
    something obvious. I've run into (what looks like) a strange
    inconsistency in the language. Anyway, I have a setup where I
    initialize a class object within another class, and then have to
    overload one of the new object's functions:

    BEGIN SAMPLE CODE:

    class A:
    def __init__(self):
    pass

    def setFunction(self, fromFunc, toFunc):
    fromFunc = toFunc

    def myPrint(self):
    print 'Old'


    class myClass:
    def __init__(self):
    a = A()

    #a.setFunction(a.myPrint, self.newPrint)
    a.myPrint = self.newPrint

    a.myPrint()

    def newPrint(self):
    print 'New'


    b = myClass()


    END SAMPLE CODE

    The code above works fine, and prints out 'New' like it should.
    However, when I try to use the commented line (a.setFunction...)
    instead of (a.myPrint = self.newPrint), the a.myPrint function is not
    getting overloaded and still prints out 'Old'. It seems to me that
    since I'm passing both method instance objects to a.setFunction(),
    there should be no problem overloading them. Is there a way I can do
    this with a function call? It's important for this system to have a
    generic method for overloading functions...
    I'm not quite sure to understand what you're trying to do, but I dont
    see what is has to do with overloading...

    First let have a look on your code :
    class A:
    def __init__(self):
    pass >
    def setFunction(self, fromFunc, toFunc):
    fromFunc = toFunc
    Why do you need to make this a method ? It could (and should IMHO) be
    either a function or a static method. (hint : 'self' is not used)
    def myPrint(self):
    print 'Old'
    >
    >
    class myClass:
    def __init__(self):
    a = A()
    #a.setFunction(a.myPrint, self.newPrint)
    Ok, this just can't work because a method *is not* just a function.
    a.myPrint = self.newPrint
    This is a more simple way to do it, and that ones work !-)
    a.myPrint() >
    def newPrint(self):
    print 'New'
    >
    >
    b = myClass()
    >

    Ok, now where are you overloading a function ?

    Usually (please correct me if i'm wrong), "overloading" a function means
    "having two (or more) functions with the same name but different
    argument lists". This is a 'feature' of languages like C++ or Java, but
    not of Python (where you could use some other way to achieve this).

    What you're doing here is 'replacing' an instance method with another
    one (I guess in Python's parlance, we should say 'rebinding').

    If what you're trying to do is just that (replacing an instance method),
    do it the simplest way (the one that is not commented in your code).

    Now if you want to 'replace' a method for all existing instances of a
    class, I leave it up to some __class__ Guru !-)

    Laotseu
  • Laotseu at Jan 9, 2003 at 4:51 am
    laotseu wrote:
    (snip)
    What you're doing here is 'replacing' an instance method with another
    one (I guess in Python's parlance, we should say 'rebinding').

    If what you're trying to do is just that (replacing an instance method),
    do it the simplest way (the one that is not commented in your code).

    Now if you want to 'replace' a method for all existing instances of a
    class, I leave it up to some __class__ Guru !-)

    Laotseu
    Ok, I got it a few minutes later :

    class Truc:
    def test(self):
    print "old test"

    a = Truc()

    def test2(self):
    print "new test"

    a.__class__.test = test2
    a.test()
    new test
    Laotseu
  • Laotseu at Jan 10, 2003 at 5:41 am

    Dennis Lee Bieber wrote:
    laotseu fed this fish to the penguins on Wednesday 08 January 2003
    08:51 pm:


    Ok, I got it a few minutes later :

    class Truc:
    def test(self):
    print "old test"

    a = Truc()

    def test2(self):
    print "new test"

    a.__class__.test = test2
    a.test()
    new test
    Of course, that has just changed the class definition. Did you really
    want that?
    In that case, yes, but I may not have made it clear (it was the answer
    to the last question in my previous post).

    (snip code)

    Laotseu
  • Sean at Jan 9, 2003 at 2:49 pm
    Thank you everyone for the advice!

    Peter and Laotseu: Yeah, I new 'overloading' wasn't the right term,
    but I'm still a C++ guy at heart and I had no idea what the correct
    term would be.

    Jack: Unfortunatly, inheritance was not an option and I had to make
    sure only that specific instance's method was getting rebound.

    Jeff's solution was the one that worked best for this system. I know
    it's a really strange thing to have to do, but I'm building this
    system for other people to develop on and I need to have a way of
    knowing when they want to rebind a method. Thanks everyone!

    -Sean

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJan 8, '03 at 8:34p
activeJan 10, '03 at 5:41a
posts8
users5
websitepython.org

People

Translate

site design / logo © 2022 Grokbase