我在Python out1,out2,out3等中有很多函数,并希望根据我传入的整数来调用它们。
def arryofPointersToFns (value):
#call outn where n = value
有一种简单的方法吗?
答案 0 :(得分:31)
tl; dr:写一个out(n)
函数而不是out1(), out2(), ..., outN()
,不要理会这个hack。
我无法想象这个问题会在实践中出现的合理情况。请重新考虑问题的架构;有可能有一个更好的方法来做到这一点(因为将它们存储在列表中意味着除了索引之外的函数没有任何意义;例如,我只能想象如果你创建的话你想要这样做一堆动态生成的thunk,它们的时序有问题,或类似的东西)。特别是你正在阅读这个答案的任何新手用户,考虑制作一个更通用的功能,可以处理所有事情,或者将每个功能与一些更多的识别信息相关联,或者将其作为一个类的一部分,等等。
那就是说,你就是这样做的。
myFuncs = [f0,f1,f2]
myFuncs[2](...) #calls f2
或
myFuncs = {'alice':f1, 'bob':f2}
myFuncs['alice'](...) #calls f1
这只是一步中的以下两个步骤:
myFuncs = [f0,f1,f2]
f = myFuncs[i]
f(...) #calls fi
或者如果你没有上面提到的OP函数'myFunc'的注册表,你可以使用globals(),虽然它是非常hack形式并且要避免(除非你希望这些函数可用于你的模块命名空间,在这种情况下可能很好......但这种情况可能很少,你可能宁愿在子模块中定义这些函数然后from mysubmodule import *
它们,这反过来又略微不赞成):
def fN(n):
return globals()['f'+str(n)]
def f2():
print("2 was called!")
fN(2)(...) #calls f2
这里有另外两个想法(在回答被接受后添加,前两个评论):
您还可以创建这样的装饰器:
>>> 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
装饰器以跟踪索引并执行以下操作:
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()
,您可以定义一个类:
class Funcs(object):
def f1():
...
def f2():
...
def num(n):
[code goes here]
如果您的功能数量很少,您可以使用['f1','f2','f3'][i]
。
当然没有进一步的信息,所有这些建议都只是忽略了真正的问题:这种情况永远不会出现,并且可能是严重的架构缺陷的标志,当你可能宁愿拥有某些东西时(使用你的例如:
# 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):
# ???
答案 1 :(得分:1)
实际上,我确实存在这个问题并且非常现实:我需要显示一个表,其中每一行都需要一种完全不同的方法来组成单元格内容。我的解决方案是创建一个返回空值的类,然后将其子类化并实现不同的值方法,然后将每个子类实例化为一个数组,然后根据行号调用实例的方法。通过使子类成为表生成器类的内部来限制全局命名空间的压缩。代码看起来像这样:
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'方法以指示如何使用内部类的任意名称提供行标题。该方法还具有可以容易地实现合适的“尺寸”方法的优点。这些行将以与它们在代码中出现的顺序相同的顺序出现在输出中,但这可能是一个优势。
注意:上面没有经过测试的代码,只是我实际编写的代码的一个例子来说明一种方法。
答案 2 :(得分:1)
一个人可以通过字典访问方法:
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()
答案 3 :(得分:0)
def array(ar=[]):
ar = np.array(ar)
return ar