tl; dr: написать функцию out(n)
вместо out1(), out2(), ..., outN()
и не беспокоиться об этом хаке.
Я не могу представить разумный сценарий, когда этот вопрос возникнет на практике. Пожалуйста, пересмотрите архитектуру проблемы; вероятно, есть гораздо лучший способ сделать это (поскольку их хранение в списке подразумевает, что в функциях нет ничего значащего, кроме индекса; например, я могу только представить, что вы захотите сделать это, если вы создаете группа динамически генерируемых thunks, где их временное упорядочение имеет значение, или что-то подобное). Особенно для начинающих пользователей, которые читают этот ответ, подумайте над созданием более общей функции, которая может обрабатывать все, или связыванием с каждой функцией более идентифицирующей информации или прикреплением ее как части класса и т. Д.
Тем не менее, вот как ты это сделаешь.
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
или если у вас нет реестра функций 'myFunc', подобного описанному выше OP, вы можете использовать globals (), хотя это чрезвычайно хакерская форма, и ее следует избегать (если вы не хотите, чтобы эти функции были доступны в пространство имен вашего модуля, в этом случае, может быть, это нормально ... но это, вероятно, редко, и вы, вероятно, предпочтительнее определить эти функции в подмодуле, чем 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):
# ???