Adding new methods to new-style classes dynamically

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Max Derkachev

    #1

    Adding new methods to new-style classes dynamically

    Good day to all.

    Some time ago I'd been playing with a framework which uses dynamic
    class creation havily. Say, I could do:

    class A:
    pass

    # I method name is dynamic
    meth_name = 'foo'

    #method code can also be dynamic - any executable object will be good
    enough
    func = lambda self: self.__class__. __name__

    A.__dict__[meth_name] = func
    a = A()
    print a.foo()[color=blue][color=green]
    >> A[/color][/color]
    # methods could be added/changed at runtime, without re-instantination
    A.__dict__[meth_name] = lambda self: type(self)
    print a.foo()[color=blue][color=green]
    >> <type 'instance'>[/color][/color]

    #well, try this with the new-style class
    class A(object):
    pass

    # the new-style __dict__ is a dictproxy object
    A.__dict__[meth_name] = lambda self: type(self)[color=blue][color=green]
    >>Traceback (most recent call last):
    >> File "<interacti ve input>", line 1, in ?
    >>TypeError: object does not support item assignment[/color][/color]


    Of course, I can do
    A.foo = some_executable _object
    But that does help when a dynamic method name is needed.
    Another option is:
    exec('A.%s = %s'%('foo', 'some_executabl e_option'))
    But I don't like eval'ling things :)

    Is there other way to add/change methods to new-style classes
    dynamically?

  • Michele Simionato

    #2
    Re: Adding new methods to new-style classes dynamically

    Do you mean setattr?

    setattr(A, meth_name, lambda self: type(self))


    Michele Simionato

    Comment

    • John Machin

      #3
      Re: Adding new methods to new-style classes dynamically

      Max Derkachev wrote:
      [snip][color=blue]
      > #well, try this with the new-style class
      > class A(object):
      > pass
      >
      > # the new-style __dict__ is a dictproxy object
      > A.__dict__[meth_name] = lambda self: type(self)[color=green][color=darkred]
      > >>Traceback (most recent call last):
      > >> File "<interacti ve input>", line 1, in ?
      > >>TypeError: object does not support item assignment[/color][/color]
      >
      >
      > Of course, I can do
      > A.foo = some_executable _object
      > But that does help when a dynamic method name is needed.
      > Another option is:
      > exec('A.%s = %s'%('foo', 'some_executabl e_option'))
      > But I don't like eval'ling things :)
      >
      > Is there other way to add/change methods to new-style classes
      > dynamically?[/color]

      Ever considered setattr()? Not only does it appear to do the job but
      also it avoids those __make__your__e yes__bleed__ double underscores.
      [color=blue][color=green][color=darkred]
      >>> class A(object):[/color][/color][/color]
      .... pass
      ....[color=blue][color=green][color=darkred]
      >>> A.__dict__['foo'] = 123[/color][/color][/color]
      Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      TypeError: object does not support item assignment[color=blue][color=green][color=darkred]
      >>> setattr(A, 'foo', 123)
      >>> A.foo[/color][/color][/color]
      123[color=blue][color=green][color=darkred]
      >>>>>> def bar(self):[/color][/color][/color]
      .... print 'bar bar blog ship'
      ....[color=blue][color=green][color=darkred]
      >>> setattr(A, 'bar', bar)
      >>> eh = A()
      >>> eh.bar()[/color][/color][/color]
      bar bar blog ship[color=blue][color=green][color=darkred]
      >>>[/color][/color][/color]

      HTH,
      John

      Comment

      • Max Derkachev

        #4
        Re: Adding new methods to new-style classes dynamically


        John Machin wrote:[color=blue][color=green][color=darkred]
        > >>> A.foo[/color][/color]
        > 123[/color]

        Oh, I've been a little dumb to forget about it :)
        Thanks.

        Max.

        Comment

        • Jack Diederich

          #5
          Re: Adding new methods to new-style classes dynamically

          On Thu, May 05, 2005 at 01:35:09AM -0700, Max Derkachev wrote:[color=blue]
          > Good day to all.
          >
          > Some time ago I'd been playing with a framework which uses dynamic
          > class creation havily. Say, I could do:[/color]
          <snip>[color=blue]
          >
          > #well, try this with the new-style class
          > class A(object):
          > pass
          >
          > # the new-style __dict__ is a dictproxy object
          > A.__dict__[meth_name] = lambda self: type(self)[color=green][color=darkred]
          > >>Traceback (most recent call last):
          > >> File "<interacti ve input>", line 1, in ?
          > >>TypeError: object does not support item assignment[/color][/color]
          >
          > Is there other way to add/change methods to new-style classes
          > dynamically?[/color]
          [color=blue][color=green][color=darkred]
          >>> import new
          >>> dir(new)[/color][/color][/color]
          ['__builtins__', '__doc__', '__file__', '__name__', 'classobj', 'code', 'function', 'instance', 'instancemethod ', 'module'][color=blue][color=green][color=darkred]
          >>> def foo(self):[/color][/color][/color]
          .... print "FOO!"[color=blue][color=green][color=darkred]
          >>> A.foo = new.instancemet hod(foo, None, A) # func, object, class
          >>> A.foo[/color][/color][/color]
          <unbound method A.foo>[color=blue][color=green][color=darkred]
          >>> a = A()
          >>> a.foo[/color][/color][/color]
          <bound method A.foo of <__main__.A object at 0xb7e0b4cc>>[color=blue][color=green][color=darkred]
          >>> a.foo()[/color][/color][/color]
          FOO!

          -jackdied


          Comment

          Working...