indirect function calls and variable variables
Bengt Richter
bokr at oz.net
Wed May 21 19:24:13 EDT 2003
On Wed, 21 May 2003 04:35:55 GMT, Randall Smith <randall at tnr.cc> wrote:
>Question: Is it feasible to make indirect function calls in python?
>
>Example:
>
>
>def f1():
> blah blah
> blah blah
>def f2():
> foo doo
> doo foo
>def f3():
> yik yak
> mee yow
>def fInfinity():
> yo yo
> yaw yaw
>
>#what i'm trying to avoid
>def do_f(f):
> if f == 'f1': f1()
> if f == 'f2': f2()
> if f == 'f3': f3()
> if f == 'fInfinity': youGetThePoint()
>
>#what i'd like to do instead
>def do_f(f):
> f() # this doesn't work, but maybe you get the point.
>
I'd try something like (note that do_g is more general than do_f, since you can
pass arguments via it -- though I'm not sure __get__ will continue to work the
way I used it. Seems useful though ;-): Of course, with do_g you can't override
the module as is, but we could override it with a special keyword arg, e.g.,
_UseThisModule, if present, and delete it before passing to the named function.
I'll leave that as an excercise ;-)
====< RandallSmith.py >=============================
def f1(): return 'f1 here'
def f2(): return 'f2 here'
def f3(oneArg): return 'f3 here with %r' % oneArg
def f4(*args, **kw): return 'f4 here with %r, %r' %(args, kw)
def do_f(f, theModule = __import__(__name__)): # default to current module
# (disallow non-module overriding arg)
assert isinstance(theModule, __builtins__.__class__), '2nd do_f arg must be module'
return getattr(theModule, f)()
def do_g(theModule, f, *args, **kw):
return getattr(theModule, f)(*args, **kw)
do_g = do_g.__get__(__import__(__name__)) # bind theModule like self in a bound method
if __name__ == '__main__':
def showargs(fn, *args, **kw):
pieces = [`fn`]
if args: pieces.append(', '.join(map(repr, args)))
if kw: pieces.append(', '.join(['%s=%r' % (k,v) for k,v in kw.items()]))
return ', '.join(pieces)
for funName, args, kw in zip('f1 f2 f2 f3 f3 f4 f4'.split(),
[(), (), ('f2 bad',), (), ('f3 one ok',), (), ('f41', 'f42')],
[{}, {}, {}, {}, {}, {}, {'f4key':'f4val'}]):
print ' do_f(%s) =>' % showargs(funName, *args, **kw),
try:
print do_f(funName, *args, **kw)
except Exception, e:
print '\n%s: %s' % (e.__class__.__name__, e)
print ' do_g(%s) =>' % showargs(funName, *args, **kw),
try:
print do_g(funName, *args, **kw)
except Exception, e:
print '\n%s: %s' % (e.__class__.__name__, e)
====================================================
Result of running it:
[15:56] C:\pywk\clp>RandallSmith.py
do_f('f1') => f1 here
do_g('f1') => f1 here
do_f('f2') => f2 here
do_g('f2') => f2 here
do_f('f2', 'f2 bad') =>
AssertionError: 2nd do_f arg must be module
do_g('f2', 'f2 bad') =>
TypeError: f2() takes no arguments (1 given)
do_f('f3') =>
TypeError: f3() takes exactly 1 argument (0 given)
do_g('f3') =>
TypeError: f3() takes exactly 1 argument (0 given)
do_f('f3', 'f3 one ok') =>
AssertionError: 2nd do_f arg must be module
do_g('f3', 'f3 one ok') => f3 here with 'f3 one ok'
do_f('f4') => f4 here with (), {}
do_g('f4') => f4 here with (), {}
do_f('f4', 'f41', 'f42', f4key='f4val') =>
TypeError: do_f() takes at most 2 non-keyword arguments (3 given)
do_g('f4', 'f41', 'f42', f4key='f4val') => f4 here with ('f41', 'f42'), {'f4key': 'f4val'}
>
>
>While I'm at it, can Python do variable variables?
>In PHP:
> $var = 'hey'
> $$var = 'dude'
>
> echo $dude
>
> output: hey
>
>I used this alot in PHP. Is there a way to do it in Python?
Probably, but I'm not sure what you mean.
Regards,
Bengt Richter
More information about the Python-list
mailing list