Python中通过数组索引调用函数

Python中通过数组索引调用函数,python,delegates,Python,Delegates,我在Python中有一系列函数out1、out2、out3等,我想根据传入的整数调用它们 def arryofPointersToFns (value): #call outn where n = value 有没有一种简单的方法可以做到这一点;dr:编写一个out(n)函数,而不是out1(),out2(),…,outN(),这样就不用麻烦了 我无法想象在实践中会出现这个问题的合理情况。请重新考虑问题的结构;可能有更好的方法来实现这一点(因为将它们存储在列表中意味着除了索引之外,函

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

def arryofPointersToFns (value):
     #call outn where n = value
有没有一种简单的方法可以做到这一点;dr:编写一个
out(n)
函数,而不是
out1(),out2(),…,outN()
,这样就不用麻烦了

我无法想象在实践中会出现这个问题的合理情况。请重新考虑问题的结构;可能有更好的方法来实现这一点(因为将它们存储在列表中意味着除了索引之外,函数没有任何意义;例如,我只能想象,如果您正在创建一组动态生成的thunk,它们的时间顺序很重要,或者类似的东西,那么您会希望这样做)。特别是任何新手用户,你正在阅读这个答案,考虑做一个更一般的功能,可以处理一切,或者与每个函数关联一些更多的识别信息,或者把它作为一个类的一部分,等等。

也就是说,这就是你要做的

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

这只是一个步骤中的以下两个步骤:

myFuncs = [f0,f1,f2]
f = myFuncs[i]
f(...) #calls fi
或者,如果您没有上面提到的函数“myFunc”的注册表,您可以使用globals(),尽管这是一种非常粗糙的形式,需要避免(除非您希望这些函数在您的模块名称空间中可用,在这种情况下可能没问题……但这种情况可能很少发生,您可能更希望在子模块中定义这些函数,然后从mysubmodule import*中定义它们,这一点也有点不赞成):


以下是另外两个想法(在接受答案和前两条评论后添加):

您还可以创建这样的装饰器:

>>> 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
class Table(object):
    class Row(object):
        def name(self):
            return self.__class__.__name__
    class Row1(Row):
        def value(self):
            return 'A'
    class Row2(Row):
        def value(self):
            return 'B'
    class Row3(Row):
        def value(self):
            return 'C'
    def __init__(self):
        self._rows = []
        for row in self.Row.__subclasses__():
            self._row.append(row())
    def number_of_rows(self):
        return len(self._rows)
    def value(self,rownumber):
        return self._rows[rownumber].value()
并像这样使用它:

>>> 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>}
或者,为了避免
globals()
,您可以定义一个类:

class Funcs(object):
    def f1():
        ...
    def f2():
        ...
    def num(n):
        [code goes here]
如果您的函数数量很小,则可以使用
['f1','f2','f3'][i]

当然,如果没有进一步的信息,所有这些建议都只是忽略了真正的问题:这种情况永远不会出现,并且可能是严重架构缺陷的迹象,而您可能更希望(使用您的示例)有这样的东西:

而不是

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

事实上,我确实有这个问题,而且非常现实:我需要显示一个表,其中每一行都需要一个完全不同的方法来组成单元格内容。我的解决方案是创建一个返回空值的类,然后对它进行子类化并实现不同的值方法,然后将每个子类实例化为一个数组,然后调用实例的方法取决于行号。全局命名空间污染通过使子类位于表生成器类的内部而受到限制。代码如下所示:

>>> 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
class Table(object):
    class Row(object):
        def name(self):
            return self.__class__.__name__
    class Row1(Row):
        def value(self):
            return 'A'
    class Row2(Row):
        def value(self):
            return 'B'
    class Row3(Row):
        def value(self):
            return 'C'
    def __init__(self):
        self._rows = []
        for row in self.Row.__subclasses__():
            self._row.append(row())
    def number_of_rows(self):
        return len(self._rows)
    def value(self,rownumber):
        return self._rows[rownumber].value()
显然,在一个实际的示例中,每个子类值方法都会有很大的不同。“name”方法用于指示如何在需要时使用内部类的任意名称提供行标题。这种方法还有一个优点,即可以轻松实现合适的“size”方法。行将显示在输出顺序与它们在代码中出现的顺序相同,但这可能是一个优势


注意:以上不是经过测试的代码,只是我的实际代码的一部分,用于说明一种方法。

可以通过字典访问方法:

def one1():
    print("Method one1 called")
def one2():
    print("Method one2 called")
def one3():
    print("Method one3 called")
methodDictionary = {1: one1, 2:one2, 3: one3}
method1 = methodDictionary[1]
method1()
method2 = methodDictionary[2]
method2()
method3 = methodDictionary[3]
method3()

尽管后者只有在一些穷人没有意识到真正的解决方案时才被接受(阅读:前两个和类似的解决方案)让你陷入全局函数的困境,
f0
f1
,等等。别那么傻了。注意,使用全局函数通常是一个糟糕的计划。把你的函数放在一个列表中几乎总是一个更好的主意。@Winston Ewert;你会如何按照你的建议使用一个列表来写这个呢?@Weholt,答案已经在s之前解释了怎么做如何使用globals()?
  def array(ar=[]):
     ar = np.array(ar)
     return ar
class Table(object):
    class Row(object):
        def name(self):
            return self.__class__.__name__
    class Row1(Row):
        def value(self):
            return 'A'
    class Row2(Row):
        def value(self):
            return 'B'
    class Row3(Row):
        def value(self):
            return 'C'
    def __init__(self):
        self._rows = []
        for row in self.Row.__subclasses__():
            self._row.append(row())
    def number_of_rows(self):
        return len(self._rows)
    def value(self,rownumber):
        return self._rows[rownumber].value()
def one1():
    print("Method one1 called")
def one2():
    print("Method one2 called")
def one3():
    print("Method one3 called")
methodDictionary = {1: one1, 2:one2, 3: one3}
method1 = methodDictionary[1]
method1()
method2 = methodDictionary[2]
method2()
method3 = methodDictionary[3]
method3()