Python中通过数组索引调用函数 [英] Calling functions by array index in Python

查看:31
本文介绍了Python中通过数组索引调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Python out1、out2、out3 等中有一堆函数,我想根据我传入的整数调用它们.

I have a bunch of functions in Python out1, out2, out3 etc. and would like to call them based on an integer I pass in.

def arryofPointersToFns (value):
     #call outn where n = value

有没有简单的方法可以做到这一点?

Is there an easy way to do this?

推荐答案

tl;dr: 写一个 out(n) 函数而不是 out1(), out2(), ..., outN() 并且不要打扰这个黑客.

tl;dr: Write an out(n) function rather than out1(), out2(), ..., outN() and don't bother with this hack.

我无法想象在实践中会出现这个问题的合理场景.请重新考虑问题的架构;可能有更好的方法来做到这一点(因为将它们存储在列表中意味着除了索引之外的函数没有任何意义;例如,我只能想象如果你正在创建你想要这样做一堆动态生成的 thunk,它们的时间顺序很重要,或者类似的东西).尤其是您正在阅读此答案的任何新手用户,请考虑制作一个可以处理所有内容的更通用的函数,或者为每个函数关联更多的识别信息,或者将其作为类的一部分等等.

I cannot imagine a reasonable scenario where this question would come up in practice. Please reconsider the architecture of the problem; there is likely to be a much better way to do this (because storing them in a list implies there is nothing meaningful about the functions except the index; for example, I can only imagine that you'd want to do this if you were creating a bunch of dynamically-generated thunks where their temporal ordering matters, or something similar). Especially any novice users you are reading this answer, consider making a more general function that can handle everything, or associating to each function some more identifying information, or sticking it as part of a class, etc.

也就是说,这就是你的做法.

That said, this is how you'd do it.

myFuncs = [f0,f1,f2]
myFuncs[2](...) #calls f2

myFuncs = {'alice':f1, 'bob':f2}
myFuncs['alice'](...) #calls f1

这只是以下两步合二为一:

this is just the following two steps in one step:

myFuncs = [f0,f1,f2]
f = myFuncs[i]
f(...) #calls fi

或者,如果您没有像上面所说的 OP 那样的函数 'myFunc' 的注册表,您可以使用 globals(),尽管它是一种非常骇人听闻的形式并且应该避免(除非您希望这些函数在你的模块命名空间,在这种情况下可能没问题......但这可能很少见,你可能宁愿在子模块中定义这些函数,然后 from mysubmodule import * 它们,它在微微皱眉):

or if you don't have a registry of functions 'myFunc' like the OP said above, you can use globals(), though it is extremely hackish form and to be avoided (unless you want those functions to be available in your module namespace, in which case maybe it's fine... but this is probably rarely the case, and you'd probably rather define those functions in a submodule then from mysubmodule import * them, which is in turn slightly frowned upon):

def fN(n):
    return globals()['f'+str(n)]

def f2():
    print("2 was called!")

fN(2)(...) #calls f2

<小时>

这里有两个其他想法(在接受答案和前两条评论后添加):


here are two other ideas (added after answer was accepted and first two comments):

你也可以像这样创建一个装饰器:

You can also create a decorator like this:

>>> def makeRegistrar():
...     registry = {}
...     def registrar(func):
...         registry[func.__name__] = func
...         return func  # normally a decorator returns a wrapped function, 
...                      # but here we return func unmodified, after registering it
...     registrar.all = registry
...     return registrar

并像这样使用它:

>>> reg = makeRegistrar()
>>> @reg
... def f1(a):
...  return a+1
... 
>>> @reg
... def f2(a,b):
...  return a+b
... 
>>> reg.all
{'f1': <function f1 at 0x7fc24c381958>, 'f2': <function f2 at 0x7fc24c3819e0>}

然后你可以调用 reg.all['f1'].您可以调整 reg 装饰器以跟踪索引并执行以下操作:

then you can call reg.all['f1']. You could adapt the reg decorator to keep track of the indexing and do something like:

registry = []
index = int(re.regextofindthenumber(func.__name__))
if not index==len(registry):
    raise Exception('Expected def f{} but got def f{}')
else:
    registry[index] = func

或者,为了避免 globals(),您可以定义一个类:

Alternatively, to avoid globals(), you could define a class:

class Funcs(object):
    def f1():
        ...
    def f2():
        ...
    def num(n):
        [code goes here]

如果您的函数数量很少,您可以使用 ['f1','f2','f3'][i].

If your number of functions is small, you could get away with ['f1','f2','f3'][i].

当然,没有更多信息,所有这些建议都只是忽略了真正的问题:这种情况永远不应该出现,并且可能是严重架构缺陷的迹象,而您可能更愿意拥有一些东西(使用您的示例)喜欢:

Of course without further information, all these suggestions are just ignoring the real problem: this situation should never come up, and is a possibly a sign of a serious architecture flaw, when you'd probably rather have something (to use your example) like:

# a possibly-better world
def out(n):
    # output to N, whatever that means

而不是

# what you have now
def out1():
    # output to 1
def out2():
    # output to 2
def outN(n):
    # ???

这篇关于Python中通过数组索引调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆