Указатель на функцию Python - PullRequest
       14

Указатель на функцию Python

66 голосов
/ 17 февраля 2010

У меня есть имя функции, хранящееся в такой переменной:

myvar = 'mypackage.mymodule.myfunction'

, и теперь я хочу вызвать myfunction следующим образом

myvar(parameter1, parameter2)

Какой самый простой способ добиться этого?

Ответы [ 8 ]

96 голосов
/ 17 февраля 2010
funcdict = {
  'mypackage.mymodule.myfunction': mypackage.mymodule.myfunction,
    ....
}

funcdict[myvar](parameter1, parameter2)
35 голосов
/ 17 февраля 2010

Гораздо приятнее иметь возможность просто хранить саму функцию, поскольку они являются первоклассными объектами в python.

import mypackage

myfunc = mypackage.mymodule.myfunction
myfunc(parameter1, parameter2)

Но, если вам нужно импортировать пакет динамически, вы можете достичь этого с помощью:

mypackage = __import__('mypackage')
mymodule = getattr(mypackage, 'mymodule')
myfunction = getattr(mymodule, 'myfunction')

myfunction(parameter1, parameter2)

Имейте в виду, однако, что вся эта работа относится к любой области, в которой вы находитесь. Если вы не сохраните их каким-либо образом, вы не можете рассчитывать на то, что они останутся, если вы покинете локальную область.

12 голосов
/ 17 февраля 2010
def f(a,b):
    return a+b

xx = 'f'
print eval('%s(%s,%s)'%(xx,2,3))

OUTPUT

 5
8 голосов
/ 17 февраля 2010

1001 * легкий *

eval(myvar)(parameter1, parameter2)

У вас нет функции "указатель". У вас есть функция «имя».

Хотя это работает хорошо, большое количество людей скажет вам, что это «небезопасно» или «риск для безопасности».

5 голосов
/ 17 февраля 2010

Почему бы не сохранить саму функцию? myvar = mypackage.mymodule.myfunction намного чище.

4 голосов
/ 17 февраля 2010
modname, funcname = myvar.rsplit('.', 1)
getattr(sys.modules[modname], funcname)(parameter1, parameter2)
2 голосов
/ 07 июля 2016

Я столкнулся с подобной проблемой при создании библиотеки для обработки аутентификации. Я хочу, чтобы владелец приложения, используя мою библиотеку, мог зарегистрировать обратный вызов в библиотеке для проверки авторизации для групп LDAP, в которых находится аутентифицированный человек. Конфигурация передается в виде файла config.py, который импортируется и содержит в все параметры конфигурации.

Я получил это на работу:

>>> class MyClass(object):
...     def target_func(self):
...         print "made it!"
...    
...     def __init__(self,config):
...         self.config = config
...         self.config['funcname'] = getattr(self,self.config['funcname'])
...         self.config['funcname']()
... 
>>> instance = MyClass({'funcname':'target_func'})
made it!

Есть ли питон-э-э способ сделать это?

2 голосов
/ 02 июня 2014

eval(compile(myvar,'<str>','eval'))(myargs)

compile (..., 'eval') допускает только один оператор, так что после вызова не может быть произвольных команд, или возникнет ошибка SyntaxError.Тогда небольшая проверка может по крайней мере ограничить выражение чем-то в вашем распоряжении, например, начать тестирование mypackage.

...