Why instancemethod when I can add functions to classes outside class body?

Discussion in 'Python' started by Rim, Jul 25, 2003.

  1. Rim

    Rim Guest

    Hi,

    It appears to me the simplest way to add a function to a class outside
    of the class declaration is as follows:

    >>> class a(object):

    .... pass
    ....
    >>> def f(self):

    .... print 'hi'
    ....
    >>> a.f = f
    >>> b=a()
    >>> b.f()

    hi

    It works even when the class and the function are in defined in
    different modules,
    and the call to the method in a third module.

    So what problem is the new.instancemethod() trying to solve?

    It is ok to point me to a PEP or the like.

    Thanks,
    - Rim
    Rim, Jul 25, 2003
    #1
    1. Advertising

  2. (Rim) writes:

    > So what problem is the new.instancemethod() trying to solve?


    It has no side effects on the class it is an instancemethod of.

    Regards,
    Martin
    Martin v. =?iso-8859-15?q?L=F6wis?=, Jul 25, 2003
    #2
    1. Advertising

  3. Rim

    Ben Finney Guest

    On 25 Jul 2003 07:18:15 +0200, Martin v. Löwis wrote:
    > (Rim) writes:
    >> So what problem is the new.instancemethod() trying to solve?

    >
    > It has no side effects on the class it is an instancemethod of.


    So what side effects (i.e. what problem) is the new.instancemethod()
    trying to solve?

    --
    \ "I spent a lot of money on wine and women, and like a fool I |
    `\ squandered the rest." -- Benny Hill |
    _o__) |
    http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B
    Ben Finney, Jul 25, 2003
    #3
  4. "Ben Finney" <> wrote:
    > On 25 Jul 2003 07:18:15 +0200, Martin v. Löwis wrote:
    > > (Rim) writes:
    > >> So what problem is the new.instancemethod() trying to solve?

    > >
    > > It has no side effects on the class it is an instancemethod of.

    >
    > So what side effects (i.e. what problem) is the new.instancemethod()
    > trying to solve?


    Assigning to the class changes the behaviour of all instances of that
    class. new.instancemethod can be used to add a method to an
    individual instance.

    >>> class A: pass

    ....
    >>> a1 = A(); a2 = A()
    >>> a1.f = new.instancemethod(lambda self: "hi", a1, A)
    >>> a2.f()

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: A instance has no attribute 'f'
    >>> a1.f()

    'hi'


    - Anders
    Anders J. Munch, Jul 25, 2003
    #4
  5. Rim

    Terry Reedy Guest

    "Anders J. Munch" <> wrote in message
    news:3f210717$0$76049$...
    > "Ben Finney" <>

    wrote:
    > > On 25 Jul 2003 07:18:15 +0200, Martin v. Löwis wrote:
    > > > (Rim) writes:
    > > >> So what problem is the new.instancemethod() trying to solve?
    > > >
    > > > It has no side effects on the class it is an instancemethod of.

    > >
    > > So what side effects (i.e. what problem) is the

    new.instancemethod()
    > > trying to solve?

    >
    > Assigning to the class changes the behaviour of all instances of

    that class.

    Since changing the behavior of all instances is precisely the purpose
    of making such an assignment (of function to class as method), that is
    a feature, not a problem.

    > new.instancemethod can be used to add a method to an individual

    instance.
    >
    > >>> class A: pass

    > ...
    > >>> a1 = A(); a2 = A()
    > >>> a1.f = new.instancemethod(lambda self: "hi", a1, A)
    > >>> a2.f()

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > AttributeError: A instance has no attribute 'f'
    > >>> a1.f()

    > 'hi'


    So to answer the OP's question, the problem solved is that directly
    assigning a function as an instance attribute binds the function as a
    function, which means no *automatic* access to the instance and its
    other attributes. If such access is needed, the instance must be
    passed explicitly, as in
    a1.f = lambda self: repr(self)
    a1.f(a1)

    Instancemethod adds the option of wrapping instance-specific functions
    as bound methods getting the instance as an automatic first (self)
    paramater, just like with class-wide methods. In the 'hi' example
    above, since the self (psuedo)param is is ignored,
    a1.f = lambda: 'hi'
    would have the same net effect. However,
    a1.f = new.instancemethod(lambda self: repr(self), a1, A)
    requires the wrapping to avoid having to explicitly pass the instance.

    Terry J. Reedy
    Terry Reedy, Jul 25, 2003
    #5
  6. "Terry Reedy" <> writes:

    > So to answer the OP's question, the problem solved is that directly
    > assigning a function as an instance attribute binds the function as a
    > function, which means no *automatic* access to the instance and its
    > other attributes.


    To *really* answer the OP's question: API, in general, has no purpose
    - it has a function. Whether that function is useful for something
    depends on the application. So APIs don't try to solve problems
    themselves - it is the developers who solve the problems using the API.

    So one may ask "what is the problem that could be solved using
    new.instancemethod". These questions often don't have good answers,
    and I believe yours isn't much better than that the problem being
    solved is

    "Create an object of type instancemethod, given the function, the
    instance, and the class."

    Whether it is useful to create such objects depends on the
    application.

    Regards,
    Martin
    Martin v. =?iso-8859-15?q?L=F6wis?=, Jul 25, 2003
    #6
  7. Rim

    Rim Guest

    "Terry Reedy" <> wrote in message
    > > >>> class A: pass

    > ...
    > > >>> a1 = A(); a2 = A()
    > > >>> a1.f = new.instancemethod(lambda self: "hi", a1, A)
    > > >>> a2.f()

    > > Traceback (most recent call last):
    > > File "<stdin>", line 1, in ?
    > > AttributeError: A instance has no attribute 'f'
    > > >>> a1.f()

    > > 'hi'

    >
    > So to answer the OP's question, the problem solved is that directly
    > assigning a function as an instance attribute binds the function as a
    > function, which means no *automatic* access to the instance and its
    > other attributes. If such access is needed, the instance must be


    I don't understand why you say "no automatic access". If you examine
    the following, I have access to the attributes defined in the class,
    without doing anything special:

    >>> class a:

    .... def __init__(self,name):
    .... self.msg = "hi"
    .... self.name = name
    ....
    >>> def f(self):

    .... print "hello"
    .... print self.msg
    .... print self.name
    ....
    >>> a.f = f
    >>> b=a("Joe")
    >>> b.f()

    hello
    hi
    Joe

    I obviously don't understand what you are trying to explain to me.

    >So to answer the OP's question, the problem solved is that directly
    >assigning a function as an instance attribute binds the function as a
    >function, which means no *automatic* access to the instance and its
    >other attributes. If such access is needed, the instance must be
    >passed explicitly, as in
    >a1.f = lambda self: repr(self)
    >a1.f(a1)
    >
    >Instancemethod adds the option of wrapping instance-specific functions
    >as bound methods getting the instance as an automatic first (self)
    >paramater, just like with class-wide methods. In the 'hi' example



    I think someone should write the official definitions for the following
    so we all talk the same language:
    - function
    - method
    - bound method/function
    - unbound method/function
    - class-wide method/function
    - class-not-wide method/function
    - etc.

    > requires the wrapping to avoid having to explicitly pass the instance.


    I did not pass the instance and it worked in my example. I'd like to understand
    what you are trying to show me.

    Thanks,
    -Rim
    Rim, Jul 28, 2003
    #7
  8. Rim

    Terry Reedy Guest

    "Rim" <> wrote in message
    news:...
    > "Terry Reedy" <> wrote in message
    > > So to answer the OP's question, the problem solved is that

    directly
    > > assigning a function as an instance attribute binds the function

    as a
    > > function, which means no *automatic* access to the instance and

    its
    > > other attributes.


    > I don't understand why you say "no automatic access".


    Re-read the sentence again. The key point is 'assign ... as instance
    attribute'.

    > If you examine
    > the following, I have access to the attributes defined in the class,
    > without doing anything special:
    >
    > >>> class a:

    > ... def __init__(self,name):
    > ... self.msg = "hi"
    > ... self.name = name
    > ...
    > >>> def f(self):

    > ... print "hello"
    > ... print self.msg
    > ... print self.name
    > ...
    > >>> a.f = f


    a is the class, not an instance, making the new class attribute f a
    method just as if it has been part of the class statement.

    > >>> b=a("Joe")
    > >>> b.f()

    > hello
    > hi
    > Joe


    Try b.f = f instead and then call b.f() and b.f(b).

    Now try b.f = new.instancemethod(f) and then call b.f() and b.f(b).

    The results should answer your questions.

    Terry J. Reedy

    > >So to answer the OP's question, the problem solved is that directly
    > >assigning a function as an instance attribute binds the function as

    a
    > >function, which means no *automatic* access to the instance and its
    > >other attributes. If such access is needed, the instance must be
    > >passed explicitly, as in
    > >a1.f = lambda self: repr(self)
    > >a1.f(a1)
    > >
    > >Instancemethod adds the option of wrapping instance-specific

    functions
    > >as bound methods getting the instance as an automatic first (self)
    > >paramater, just like with class-wide methods. In the 'hi' example
    Terry Reedy, Jul 28, 2003
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Martin Miller
    Replies:
    1
    Views:
    342
    Peter Hansen
    Mar 12, 2005
  2. John Reese
    Replies:
    15
    Views:
    1,179
    Raymond Hettinger
    Jun 20, 2005
  3. Jim Lewis

    can't pickle instancemethod objects

    Jim Lewis, Jul 9, 2006, in forum: Python
    Replies:
    6
    Views:
    1,283
    Jim Lewis
    Jul 9, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  5. Michele Simionato
    Replies:
    2
    Views:
    1,861
    Michele Simionato
    May 23, 2008
Loading...

Share This Page