Call a classmethod on a variable class name

M

Matthew Keene

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.className
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
 
A

Arnaud Delobelle

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.className
  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

Then you can access its .bar() method directly:
... @classmethod
... def bar(cls): print 'Oh my Baz!'
...
Oh my Baz!

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

HTH
 
M

Matthew Keene

Arnaud said:
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:
... @classmethod
... def bar(cls): print 'Oh my Baz!'
...
globals()['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 !
 
G

Gary Herron

Matthew said:
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.className
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.theClass = SomeClass
...
parameters.theClass.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.className = 'SomeClass'
...
theClass = globals()[parameters.className]
parameters.theClass.bar()


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

Gary Herron
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top