У меня есть куча функций в Python out1, out2, out3 и т.д. и хотел бы назвать их на основе целого числа, которое я передаю.
def arryofPointersToFns (value):
#call outn where n = value
Есть ли простой способ сделать это?
У меня есть куча функций в Python out1, out2, out3 и т.д. и хотел бы назвать их на основе целого числа, которое я передаю.
def arryofPointersToFns (value):
#call outn where n = value
Есть ли простой способ сделать это?
tl; dr: записать функцию out(n)
, а не out1(), out2(), ..., outN()
и не беспокоиться об этом взломе.
Я не могу представить разумный сценарий, когда этот вопрос возникнет на практике. Пересмотрите архитектуру проблемы; вероятно, будет намного лучший способ сделать это (потому что хранение их в списке означает, что нет ничего значимого в функциях, кроме индекса, например, я могу только представить, что вы захотите сделать это, если бы вы создавали куча динамически генерируемых трюков, где их временный порядок имеет значение или что-то подобное). Особенно начинающие пользователи, которым вы читаете этот ответ, подумайте над тем, чтобы сделать более общую функцию, которая может обрабатывать все, или связывать каждую функцию с некоторой дополнительной идентификационной информацией или придерживаться ее как части класса и т.д.
Итак, вот как вы это сделаете.
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, как указано выше, вы можете использовать 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):
# ???
def array(ar=[]):
ar = np.array(ar)
return ar