Call a classmethod on a variable class name

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Matthew Keene

    Call a classmethod on a variable class name

    I would like to be able to call a specific classmethod on a class name
    that is going to be passed from another parameter. In other words, I
    have a call that looks something like:

    x = Foo.bar()

    and I would like to generalise this so that I can make this call on any
    particular class which provides the bar classmethod.

    I have implemented this using exec, like so:

    className = parameters.clas sName
    exec "x = " + className + ".bar()"

    but this feels somewhat clumsy. (I do have the requisite exception
    handling to cope with the supplied class not existing or not
    implementing the bar method, by the way).

    Is there any more Pythonesque way of doing this ? I guess what I'm
    probably looking for is something like the way I understand the send
    function works in Ruby
  • Arnaud Delobelle

    #2
    Re: Call a classmethod on a variable class name

    On Apr 13, 9:51 am, Matthew Keene <dfg...@yahoo.c om.auwrote:
    I would like to be able to call a specific classmethod on a class name
    that is going to be passed from another parameter.  In other words, I
    have a call that looks something like:
    >
       x = Foo.bar()
    >
    and I would like to generalise this so that I can make this call on any
    particular class which provides the bar classmethod.
    >
    I have implemented this using exec, like so:
    >
      className = parameters.clas sName
      exec "x = " + className + ".bar()"
    >
    but this feels somewhat clumsy.  (I do have the requisite exception
    handling to cope with the supplied class not existing or not
    implementing the bar method, by the way).
    >
    Is there any more Pythonesque way of doing this ?  I guess what I'm
    probably looking for is something like the way I understand the send
    function works in Ruby
    If your class lives in the current global namespace, you can get it
    with
    >>cls = globals()[classname]
    Then you can access its .bar() method directly:
    >>cls.bar()
    Example:
    >>class Foo(object):
    ... @classmethod
    ... def bar(cls): print 'Oh my Baz!'
    ...
    >>globals()['Foo']
    <class '__main__.Foo'>
    >>globals()['Foo'].bar()
    Oh my Baz!

    If your class lives in a module, just do getattr(module, classname)
    instead to get the class object.

    HTH

    --
    Arnaud

    Comment

    • Matthew Keene

      #3
      Re: Call a classmethod on a variable class name

      Arnaud Delobelle wrote:
      >
      If your class lives in the current global namespace, you can get it
      with
      >
      >>cls = globals()[classname]
      >
      Then you can access its .bar() method directly:
      >
      >>cls.bar()
      >
      Example:
      >
      >class Foo(object):
      ... @classmethod
      ... def bar(cls): print 'Oh my Baz!'
      ...
      >globals()['Foo']
      <class ' main .Foo'>
      >globals()['Foo'].bar()
      Oh my Baz!
      >
      If your class lives in a module, just do getattr(module, classname)
      instead to get the class object.
      >
      HTH
      >
      >
      Yes, that feels much nicer and works well.

      Thanks for the prompt reply !

      Comment

      • Gary Herron

        #4
        Re: Call a classmethod on a variable class name

        Matthew Keene wrote:
        I would like to be able to call a specific classmethod on a class name
        that is going to be passed from another parameter. In other words, I
        have a call that looks something like:
        >
        x = Foo.bar()
        >
        and I would like to generalise this so that I can make this call on any
        particular class which provides the bar classmethod.
        >
        I have implemented this using exec, like so:
        >
        className = parameters.clas sName
        exec "x = " + className + ".bar()"
        >
        Yuck. No. Don't do that. As a general rule, anything you could build
        and put into an exec is a functionality that is exposed more directly by
        Python.
        but this feels somewhat clumsy. (I do have the requisite exception
        handling to cope with the supplied class not existing or not
        implementing the bar method, by the way).
        >
        Is there any more Pythonesque way of doing this ? I guess what I'm
        probably looking for is something like the way I understand the send
        function works in Ruby
        >
        First off, if possible, don't pass the class name, but instead pass the
        class itself:

        class SomeClass:
        def foo():
        ... whatever...

        ...
        parameters.theC lass = SomeClass
        ...
        parameters.theC lass.bar()

        If you can't do that, then look up that class from the class name and
        make your call:

        class SomeClass:
        def foo():
        ... whatever...

        ...
        parameters.clas sName = 'SomeClass'
        ...
        theClass = globals()[parameters.clas sName]
        parameters.theC lass.bar()


        (Hint: It matters not whether foo is a classmethod, saticmathod or
        normal method.)

        Gary Herron







        Comment

        Working...