Fire Method by predefined string!

T

Tamer Higazi

Hi people!

Assume we have 2 methods, one called Fire and the other __DoSomething.

I want the param which is a string to be converted, that I can fire
directly a method. Is it somehow possible in python, instead of writing
if else statements ???!



Tamer


class(object):
def Fire(self,param)
#possible ?!
self.__param():


def _DoSomething(self):
print 'I did it!'
 
R

Roy Smith

Tamer Higazi said:
Hi people!

Assume we have 2 methods, one called Fire and the other __DoSomething.

I want the param which is a string to be converted, that I can fire
directly a method. Is it somehow possible in python, instead of writing
if else statements ???!



Tamer


class(object):
def Fire(self,param)
#possible ?!
self.__param():


def _DoSomething(self):
print 'I did it!'

I'm not sure why you'd want to do this, but it's certainly possible (as,
I imagine it would be, in any language that has introspection). You can
use getattr() to look up an attribute by name. Here's a little program
which demonstrates this:

class C:
def Fire(self, param):
print "I'm Fire"
try:
f = getattr(self, param)
f()
except AttributeError as ex:
print "==> %s" % ex

def _DoSomething(self):
print "I'm _DoSomething"

if __name__ == '__main__':
c = C()
c.Fire("_DoSomething")
c.Fire("blah")



$ python s.py
I'm Fire
I'm _DoSomething
I'm Fire
==> C instance has no attribute 'blah'

One thing to be aware of is that a single underscore in front of a name
is fine, but a double underscore (i.e. "__DoSomething") invokes a little
bit of Python Magic and will give you unexpected results.
 
R

Rick Johnson

class(object):
def Fire(self,param)
#possible ?!
self.__param():
def _DoSomething(self):
print 'I did it!'

1. First off your class declaration is not valid -- it needs
an identifier!

2. Never start a function or method with a lowercase letter.
Please read PEP8

3. I would advise using "self documenting names".

class Foo(object):
def envokeMethodByName(self, name):
...

But what if the method takes arguments? >:)

class Foo(object):
def envokeMethodByName(self, name, *args, **kw):
getattr(self, name)(*args, **kw)

But what if want to restrict the methods?

class Foo(object):
def __init__(self):
self.allowedNames = [
"play",
"pause",
"eject",
]
def envokeMethodByName(self, name, *args, **kw):
if name not in self.allowedNames:
raise DontAbuseMyInterfaceMan("!")
getattr(self, name)(*args, **kw)
 
R

Rick Johnson

2. Never start a function or method with a lowercase letter.
Please read PEP8

Urm... let me correct that:

2. Never start a function or method with a UPPERCASE letter.
Initial uppercase should be reserved for class names only --
and any number of leading underscores does not affect that
rule because underscores are not in the set [A-Za-z]!

You don't want these:

def __IllegalName
def _IllegalName
def IllegalName

But these are okay:

def __legalName
def _legalName
def legalName

These are preferred, however, i detest superfluous underscores!

def __legal_name
def _legal_name
def legal_name
 
S

Steven D'Aprano

I'm not sure why you'd want to do this, but it's certainly possible

It is very good for implementing the Command Dispatch pattern, which in
turn is very good for building little command interpreters or mini-
shells. Python even comes with a battery for that:


import cmd
import sys
class MyShell(cmd.Cmd):
# Override default behaviour of empty lines.
def emptyline(self):
pass
# Define commands for our shell by prefixing them with "do_".
def do_hello(self, person):
if person:
print("Hello, %s!" % person)
else:
print("Hello!")
def do_echo(self, line):
print(line)
def do_double(self, num):
print(2*float(num))
def do_bye(self, line):
return True

MyShell().cmdloop()


This defines and runs a command interpreter that understands commands
"bye", "double", "echo", "hello" and "help". (Help is predefined for you.)


See also http://drunkenpython.org/dispatcher-pattern-safety.html for
another use of command dispatch.
 

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,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top