indirect function calls and variable variables 
Author Message
 indirect function calls and variable variables

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.

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?

Randall



Sun, 06 Nov 2005 12:35:55 GMT  
 indirect function calls and variable variables

Quote:

> Question:  Is it feasible to make indirect function calls in python?
        ...
> #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.

Sure, try:

        dispatcher = {'f1': f1, 'f2': f2, 'f3': f3, ...}
        def do_f(f):
            dispatcher[f]()

Quote:
> 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?

You can do it using exec, but the best solution is a separate
dictionary.

--

 __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/  \ I'm the woman whose / Three wishes came true
\__/  Lamya



Sun, 06 Nov 2005 12:55:50 GMT  
 indirect function calls and variable variables
Quote:

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

It depends, how you want to use **do_f(f)**. Either f is
a functionpointer or a string.
1) Functionpointer (as easy, as you want):
Quote:
>>> def f1():

...     print 'f1()'
...    
Quote:
>>> def f2():

...     print 'f2()'
...    
Quote:
>>> def f3():

...     print 'f3()'
...    
Quote:
>>> def do_f(f):

...     f()
...    
Quote:
>>> do_f(f1)
f1()
>>> do_f(f2)
f2()
>>> do_f(f3)

f3()
2) As string (nearly as easy):
Quote:
>>> def do_f_asText(f):

...     eval(f)()
...    
Quote:
>>> do_f_asText('f1')

f1()
.
and so on
.

- Show quoted text -

Quote:

> 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?

Sure
>>> var='hey'
>>> dude='var'
>>> eval(dude)
'hey'
>>> var='Something else'
>>> eval(dude)
'Something else'

> Randall

Regards, Peter


Sun, 06 Nov 2005 20:39:12 GMT  
 indirect function calls and variable variables


Quote:

>> Question:  Is it feasible to make indirect function calls in python?
>    ...
>> #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.

>Sure, try:

>    dispatcher = {'f1': f1, 'f2': f2, 'f3': f3, ...}
>    def do_f(f):
>        dispatcher[f]()

>> 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?

>You can do it using exec, but the best solution is a separate
>dictionary.

                        .
                        .
                        .
I'll provide more detail.

PHPers do indeed use variable variables often--too much,
in fact.  It's a general principle that languages which
facilitate variable variables also are likely to offer
a dictionary or associative array, and most uses of
variable variables would better be recoded in terms of
dictionaries.  There are PHP folk who know this already.
If there's a question about it, someone invite me to
compl.lang.php, and I'll elaborate.

Erik illustrated the pattern with his function invocation
above.  He didn't write there that such usage generally
invites consideration for refactoring into an object-
oriented polymorphism scheme.  I leave that as an exercise
for the reader.  He also didn't observe that, yes, do_f is
feasible in a more narrow sense, using either of at least
a couple of distinct approaches.  Here's an illustration:

  def do_f(f):
          # You can do much the same with exec, instead.
      eval("%s()" % f)

  def do_f_other(f):
          # Other evaluations involve call() or __getattr__().
      (globals()[f])()

  def f1():
      print "I am f1."

  def f2():
      print "I am f2."

  do_f("f1")
  do_f("f2")
  do_f_other("f1")

Finally, can Python process variable variables?  Sure, but,
again, I'll warn you against this; there are usually better
ways:
  var = 'hey'
  dude = 'var'
  print eval(dude)

Also, your original PHP example doesn't do what you say it
does.  I leave this, too, as an exercise for the reader.
--


Business:  http://www.Phaseit.net
Personal:  http://phaseit.net/claird/home.html



Sun, 06 Nov 2005 20:41:43 GMT  
 indirect function calls and variable variables

Quote:

>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'}

Quote:

>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



Mon, 07 Nov 2005 07:24:13 GMT  
 indirect function calls and variable variables

Quote:

> PHPers do indeed use variable variables often--too much,
> in fact.  It's a general principle that languages which
> facilitate variable variables also are likely to offer
> a dictionary or associative array, and most uses of
> variable variables would better be recoded in terms of
> dictionaries.  There are PHP folk who know this already.
> If there's a question about it, someone invite me to
> compl.lang.php, and I'll elaborate.

The reason the "variable variable" phenomenon (actually "call-by-name") pops
up so much in PHP is due to its lack of support for functions as values.
However, since PHP has a single, global namespace for functions, this ends
up being an effective way to write a dispatch, and safer than an eval().

Quote:
> Erik illustrated the pattern with his function invocation
> above.  He didn't write there that such usage generally
> invites consideration for refactoring into an object-
> oriented polymorphism scheme.

I find that dispatching with an eval or dictionary lookup is often simpler
and more concise than using subtype inheritance with polymorphism. YMMV.

Dave



Fri, 11 Nov 2005 14:46:00 GMT  
 indirect function calls and variable variables


Quote:

>> PHPers do indeed use variable variables often--too much,
>> in fact.  It's a general principle that languages which

                        .
                        .
                        .

Quote:
>The reason the "variable variable" phenomenon (actually "call-by-name") pops
>up so much in PHP is due to its lack of support for functions as values.
>However, since PHP has a single, global namespace for functions, this ends
>up being an effective way to write a dispatch, and safer than an eval().

>> Erik illustrated the pattern with his function invocation
>> above.  He didn't write there that such usage generally
>> invites consideration for refactoring into an object-
>> oriented polymorphism scheme.

>I find that dispatching with an eval or dictionary lookup is often simpler
>and more concise than using subtype inheritance with polymorphism. YMMV.

>Dave

Yes and no.

I think people overdo polymorphism.  Dispatching with
a dictionary lookup is indeed often simpler and more
concise than inheritance elaboration.  You are quite
right.  I suspect we agree that the two are close,
though; when a design involves one, it's probably timely
to evaluate the other, as an alternative.

I don't follow your first paragraph.  At least one of us
doesn't understand the other.  I am writing about
"variable variables", as in the variables named
  $variable1
  $variable2
    ...
one often sees in Perl and PHP code.  My observation is
that, for several reasons, it's generally better to
transform such segments into references to
  $variable(1)
  $variable(2)
    ...
<URL: http://groups.google.com/groups?frame=left&th=4d786ca1e1b89b0c >
illustrates this.

You seem to have in mind idioms for function invocation,
rather than variable dereferencing.  Or are you making a
subtle point about one masquerading as the other?

Programmers do indeed cherish first-class functions, of
course.
--


Business:  http://www.Phaseit.net
Personal:  http://phaseit.net/claird/home.html



Sat, 12 Nov 2005 19:59:59 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. indirect function calls and variable variables

2. Class variables / global variables / Init variables

3. calling function recursively, local variables?

4. Local variables, call-back functions under Windows

5. evaluating a variable as a function call?

6. Function call or variable?

7. Function call or variable?

8. calling a variable from a separate function

9. Call a function using a variable

10. Indirect function member calls

11. Question regarding indirect function calls

12. How update variable values by calling secondary functions ?

 

 
Powered by phpBB® Forum Software