MyTetra Share
Делитесь знаниями!
Как в Python вызвать метод объекта по имени, которое написано в виде строковой переменной?
Время создания: 01.06.2023 09:40
Автор: Xintrea
Текстовые метки: python, метод, имя, строка, переменная, класс, вызов, динамически, выполнение
Раздел: Компьютер - Программирование - Язык Python
Запись: xintrea/mytetra_syncro/master/base/1685601612kzhl7jo68y/text.html на raw.github.com

Так как формально язык Python является интерпретируемым, то в нем не должно быть проблем в выполнении кода, динамически генерируемого в процессе работы программы. Однако как только начинающий программист пытается разобраться в этой теме, он сразу натыкается на какие-то странные ограничения и подходы, связанные с попыткой разработчиков языка хоть как-то ограничить возможные уязвимости, мгновенно возникающие при использовании динамически генерируемого кода.


Традиционно и не без оснований считается, что выполнение кода через eval() - это одно из самых небезопасных действий, которое можно придумать в коде программы. Поэтому для правильной работы eval() нужно еще указывать, если того требует логика вызова, глобальный и локальные контекст. Хорошая новость состоит в том, что для выполнения действия, указанного в заголовке статьи, использовать небезопасный eval() совершенно нет необходимости.


Для решения задачи вызова метода объекта по динамически сгенерированному имени (т. е. когда имя метода задано в виде строки) можно воспользоваться рефлексией, которая имеется в языке Python. Идея в том, что и у класса, и у объекта класса можно получать атрибуты с помощью функции getattr(). Атрибуты - это свойства и методы. Причем запрос атрибута происходит по имени. Если запрашиваемый атрибут является методом, то возвращается системный python-объект, представляющий запрашиваемый метод. И благодаря этому данный объект можно выполнить.


Вот пример:



class Sample():


def __init__(self):

methodName = 'runningMethod' # Имя метода как строка

result = getarrt(self, methodName)(123) # Вызов метода по имени из строки

print(result)

def runningMethod(self, a):

return a+10



Вышеуказанный код вызывает метод внутри класса. Если нужно вызвать метод снаружи, то естественно, необходимо иметь переменную которая содержит объект - экземпляр класса. И в функции getattr() вместо self надо указать эту переменную.


Кстати, можно вызывать и методы класса, а не объекта (экземпляра класса). Для этого в первом параметре функции getattr() указывается имя класса. В вышеприведенном коде это будет getattr(Sample, methodName).


Как было сказано ранее, такой способ вызова методов с динамическими именами гораздо более безопасный, чем конструирование команды и выполнение ее через функцию eval(). Для каждой задачи надо пользоваться теми инструментами, для которых они были созданы.


Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования