Вызов функции модуля с использованием его имени (строки)
602300 просмотра
12 ответа
Каков наилучший способ вызова функции по заданной строке с именем функции в программе Python. Например, предположим, что у меня есть модуль foo
, и у меня есть строка с содержимым "bar"
. Как лучше всего позвонить foo.bar()
?
Мне нужно получить возвращаемое значение функции, поэтому я не просто использую eval
. Я выяснил, как это сделать, используя eval
для определения временной функции, которая возвращает результат вызова этой функции, но я надеюсь, что есть более элегантный способ сделать это.
Ответы (12)
1791 плюса
Предполагая модуль foo
с методом bar
:
import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()
Что касается этого, строки 2 и 3 могут быть сжаты до:
result = getattr(foo, 'bar')()
если это имеет больше смысла для вашего варианта использования. getattr
Таким образом вы можете использовать методы, связанные с экземплярами классов, методы уровня модулей, методы классов ... список можно продолжить.
474 плюса
locals()["myfunction"]()
или же
globals()["myfunction"]()
locals возвращает словарь с текущей таблицей локальных символов. globals возвращает словарь с глобальной таблицей символов.
Автор: sastanin Размещён: 07.05.2009 12:45298 плюса
Решение Патрика, наверное, самое чистое. Если вам также нужно динамически подобрать модуль, вы можете импортировать его следующим образом:
module = __import__('foo')
func = getattr(module, 'bar')
func()
Автор: HS.
Размещён: 07.08.2008 11:35
94 плюса
Просто простой вклад. Если класс, который нам нужен для экземпляра, находится в том же файле, мы можем использовать что-то вроде этого:
# Get class from globals and create an instance
m = globals()['our_class']()
# Get the function (from the instance) that we need to call
func = getattr(m, 'function_name')
# Call it
func()
Например:
class A:
def __init__(self):
pass
def sampleFunc(self, arg):
print('you called sampleFunc({})'.format(arg))
m = globals()['A']()
func = getattr(m, 'sampleFunc')
func('sample arg')
# Sample, all on one line
getattr(globals()['A'](), 'sampleFunc')('sample arg')
И, если не класс:
def sampleFunc(arg):
print('you called sampleFunc({})'.format(arg))
globals()['sampleFunc']('sample arg')
Автор: Sourcegeek
Размещён: 19.08.2012 09:40
85 плюса
Получив строку с полным путем к Python пути к функции, я получил результат от указанной функции:
import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
Автор: ferrouswheel
Размещён: 16.10.2013 12:24
42 плюса
Лучший ответ в соответствии с часто задаваемыми вопросами по программированию на Python :
functions = {'myfoo': foo.bar}
mystring = 'myfoo'
if mystring in functions:
functions[mystring]()
Автор: user3946687 Размещён: 24.10.2016 01:20Основным преимуществом этого метода является то, что строки не должны совпадать с именами функций. Это также основной метод, используемый для эмуляции конструкции case.
37 плюса
Ответ (надеюсь) никто никогда не хотел
Eval как поведение
getattr(locals().get("foo") or globals().get("foo"), "bar")()
Почему бы не добавить авто-импорт
getattr(
locals().get("foo") or
globals().get("foo") or
__import__("foo"),
"bar")()
Если у нас есть дополнительные словари, которые мы хотим проверить
getattr(next((x for x in (f("foo") for f in
[locals().get, globals().get,
self.__dict__.get, __import__])
if x)),
"bar")()
Нам нужно идти глубже
getattr(next((x for x in (f("foo") for f in
([locals().get, globals().get, self.__dict__.get] +
[d.get for d in (list(dd.values()) for dd in
[locals(),globals(),self.__dict__]
if isinstance(dd,dict))
if isinstance(d,dict)] +
[__import__]))
if x)),
"bar")()
Автор: 00500005
Размещён: 09.04.2014 10:17
23 плюса
Для чего стоит, если вам нужно было передать имя функции (или класса) и имя приложения в виде строки, то вы можете сделать это:
myFnName = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn = getattr(app,myFnName)
Автор: trubliphone
Размещён: 14.02.2012 05:55
18 плюса
Попробуй это. Хотя он по-прежнему использует eval, он использует его только для вызова функции из текущего контекста . Тогда у вас есть реальная функция для использования по вашему желанию.
Основное преимущество для меня в том, что вы получите любые ошибки, связанные с eval, в момент вызова функции. Тогда при вызове вы получите только ошибки, связанные с функцией.
def say_hello(name):
print 'Hello {}!'.format(name)
# get the function by name
method_name = 'say_hello'
method = eval(method_name)
# call it like a regular function later
args = ['friend']
kwargs = {}
method(*args, **kwargs)
Автор: tvt173
Размещён: 07.12.2016 06:29
14 плюса
ничто из того, что было предложено, не помогло мне. Я обнаружил это все же.
<object>.__getattribute__(<string name>)(<params>)
Я использую Python 2.66
Надеюсь это поможет
Автор: Natdrip Размещён: 28.12.2012 04:560 плюса
Как этот вопрос Как динамически вызывать методы в классе, используя присвоение имени метода переменной [duplicate], помеченной как дубликат, как этот, я публикую соответствующий ответ здесь:
Сценарий таков: метод в классе хочет динамически вызывать другой метод в том же классе, я добавил некоторые детали в исходный пример, который предлагает более широкий сценарий и ясность:
class MyClass:
def __init__(self, i):
self.i = i
def get(self):
func = getattr(MyClass, 'function{}'.format(self.i))
func(self, 12) # This one will work
# self.func(12) # But this does NOT work.
def function1(self, p1):
print('function1: {}'.format(p1))
# do other stuff
def function2(self, p1):
print('function2: {}'.format(p1))
# do other stuff
if __name__ == "__main__":
class1 = MyClass(1)
class1.get()
class2 = MyClass(2)
class2.get()
Автор: Serjik Размещён: 26.03.2019 06:15Выход (Python 3.7.x)
функция1: 12
функция2: 12
0 плюса
Это простой ответ, это позволит вам очистить экран, например. Ниже приведены два примера с eval и exec, которые после очистки будут печатать 0 вверху (если вы используете Windows, измените clear
на cls
, пользователи Linux и Mac оставьте как есть, например) или просто выполните его соответственно.
eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Автор: Number File
Размещён: 28.08.2019 04:46
Вопросы из категории :
- python Обработка XML в Python
- python Как я могу использовать Python itertools.groupby ()?
- python Python: На какой ОС я работаю?
- python Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- python Вызов функции модуля с использованием его имени (строки)
- python Звук Питона («Колокол»)
- python Regex и unicode
- python Создать зашифрованный ZIP-файл в Python
- python Создайте базовый итератор Python
- python Функция транспонирования / распаковки (обратная сторона zip)?
- object Обнаружение неопределенного свойства объекта
- object Каков наиболее эффективный способ глубокого клонирования объекта в JavaScript?
- object Как определить равенство для двух объектов JavaScript?
- object Избегать! = Нулевые заявления
- object Как вы программно устанавливаете атрибут?
- object Каков наилучший способ сбрасывать все объекты в журнал на C #?
- object JavaScript isDOM - Как проверить, является ли объект JavaScript объектом DOM?
- object Объектная ориентация в C