Reputation: 4069
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?
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
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 are my questions:
fun_name
list in runtime? I want to save them in a text file.tmp = #algo
. Can I extract them out form those definitions while can I define the functions in runtime? I want something like this: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"]
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)())
Upvotes: 3
Views: 6482
Reputation: 9103
The typical answer to dynamical creation of functions are lambda forms:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
Probably you should use function pointers instead of lists with function names as strings. Also classes might be a concept to clean up your code, but your description is to vague to provide a more detailed answere.
Upvotes: 0
Reputation: 123782
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
Upvotes: 0
Reputation:
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.
Upvotes: 1
Reputation: 1
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)
Upvotes: 0
Reputation: 273834
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)
...
Upvotes: 1