Dynamicly define the function name and function body with variables in python
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 invok开发者_如何学Goe the function via the lst[0][x]
inside of the lst?
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 are my questions:
- Can I get the
fun_name
list in runtime? I want to save them in a text file. - I found there's a common part in function definition which is
tmp = #algo
. Can I extract them out form those definitions 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)())
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)
...
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.
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)
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
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.
精彩评论