views:

77

answers:

4

All,

I have below functions

def foo_001(para):
    tmp = para + 2
    return tmp

def foo_002(para):
    tmp = para * 2
    return tmp

def foo_003(para):
    tmp = para / 2
    return tmp

def foo_004(para):
    tmp = para - 2
    return tmp

those functions only have different in function names while the algorithm line e.g. "tmp = para - 2", besides that, the rest part are all same.

So, may I know if I can doing something like this:

def $fooname (para):         # $ is borrowed try to say fooname is a variable
    $alog                    # $algo is also variable
    return tmp

lst = [
      ['tmp = para + 2', "foo_001"],
      ['tmp = para * 2', "foo_002"],
      ['tmp = para / 2', "foo_003"],
      ['tmp = para - 2', "foo_004"],
      ]

In runtime, I can use lst[0][0] assign to $algo and using lst[0][1] assign to $fooname in somehow and I can invoke the function via the lst[0][x] inside of the lst?

Thanks!

==========

Thanks for you reply, more specific for my problem here.

file foo.py

def foo_001(para): tmp = para + 2 return tmp
def foo_002(para): tmp = para * 2 return tmp
def foo_003(para): tmp = para / 2 return tmp
...
def foo_100(para): tmp = #complex algo, return tmp

main.py

from foo import *
fun_name = ["foo_001","foo_002","foo_002" ... "foo_100"]

src = 1
rzt = [] 
for i in fun_name:
    rzt.extent(eval(i)(src)) 

here is my question:

  1. can I get the fun_name list in runtime, I want save them in a text file?
  2. I found there's common part in function defination is "tmp = #algo",can I extract them out form those definations while can I define the functions in runtime? I want something like this:

file foo.py

def foo_factory(): 
    # in somehow
    return adict      #function_name/function pair 

template = [
["foo_001","tmp = para + 2"],
["foo_002","tmp = para * 2"],
["foo_002","tmp = para * 2"],
...
["foo_100","tmp = #complex algo"]

main.py

from foo import *
dic = foo_factory(template)
fun_name = dic.keys()
src = 1
rzt = [] 
for i in fun_name:
    rzt.extent(eval(i)(src)) 
        #or
    rzt.extent(dic(i)())
+1  A: 

How are you going to call these functions if you don't know their name at "creating time"?

Wouldn't it be a better approach to hold an array of functions (closures) parametrized as you see fit?

I.e. (not tested, but should work):

def make_foo_func(op):
  def func(para):
    tmp = op(para, 2) 
    return tmp
  return func

And then:

import operator
foo_001 = make_foo_func(operator.add)
foo_oo2 = make_foo_func(operator.mul)
...
Eli Bendersky
+1  A: 

You're thinking in terms of string manipulation and named functions where you should think in terms of higher-order unnamed functions. They make this a breeze, without exploiting any dynamicness ;) (In fact, the Haskell equivalent would be considerably shorter and cleaner.)

Example:

import operator as op

def algo_factory(f):
    def algo(para):
        return f(para, 2)
    #maybe, for nicer debugging output: algo.__name__ = "..."
    return algo

algorithms = [
    mkAlgo(op.add),
    mkAlgo(op.mul),
    mkAlgo(op.truediv),
    mkAlgo(op.sub),
    #...
]

Also, depending on what you are doing, you might want algorithms to be a dict.

delnan
You've used `op` twice...
katrielalex
@katriealex: Thanks, fixed it.
delnan
A: 

I think what you really want to do is save the functions themselves in a list and retrieve the function you want from the list.

foo_container = [foo_001,foo_002,foo_003,foo_004]

Then from there, the call:

foo_container[0](3)

would be the same as:

foo_001(3)
Darrell
A: 

There are a lot of tools for manipulating functions at a high level in Python. However, from what you have written I don't understand what you're trying to do, so I can't say how to do it. So here is some rambling about things that you might find useful.

  • Don't write boilerplate code. The moment you find yourself writing the same thing that you wrote a couple of lines above, think to yourself: "how can I abstract this away?". Note that the answer might be "don't, it's easiest this way", but it also might be "aha! I can make a function factory!".

  • How on earth is making a function called foo_02 that performs division useful? I mean, clearly you're trying to simplify a more complicated problem (you are, right?) but you've removed all of the details that are useful. Think about the overall architecture of your code to work out why you need these functions.

  • Use operator a lot. It has functions for +, -, *, / and all that jazz. For instance:

    import operator as op
    operator.add(1,2) == 1 + 2
    
  • Use functools a lot. In particular, partial is your friend here:

    >>> from functools import partial
    >>> import operator as op
    >>> double = partial(op.mul, 2)
    >>> double(2)
    4
    >>> double(20)
    40
    
katrielalex