Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Python: Общие вопросы > Динамический вызов класса |
Автор: WolfAlone 23.12.2010, 17:07 |
Доброго времени суток! Есть некий класс, например class1, у него есть метод: method1, который принимает 1 или более параметров (param1, ... paramX). Метод возвращает число или строку (не принципиально). Есть список, list1, со следующим содержимым (по индексу): 0 - имя класса; 1 - имя метода; 2 - * параметр1, 2, 3 и т.д. Необходимо, обработать список и на основе его содержимого обратиться к указанному в нём классу, затем методу и передать ему параметры. Результат работы - вернуть в вызывающую функцию. Объясню суть вопроса. В PHP для подобных целей есть, например функция: __autoload(), которая позволяет подгружать файл, в котором содержится объявление необходимого класса. Имя класса и его метод могут содержаться в переменной в виде строки. Параметры в функцию или метод класса можно передавать в виде массива, при этом, каждый элемент массива будет равен 1-му параметру функции/метода. Хотелось бы узнать, как сделать подобное в Python? |
Автор: skyboy 30.12.2010, 00:26 |
http://php.net/call_user_func_array есть в PHP а для Python, как я понял. можно http://stackoverflow.com/questions/3061/calling-a-function-from-a-string-with-the-functions-name-in-python Добавлено через 1 минуту и 32 секунды а вот как передать массив параметров, как совокупность - не знаю. |
Автор: av0000 30.12.2010, 12:49 | ||||
Ну, например: как-то так (без проверок на ошибки)
UPD: Для динамической загрузке модулей смотри в сторону imp Вот кусок из моего проектика, где загружаются плагины, так, для иллюстрации:
|
Автор: bilbobagginz 7.1.2011, 18:48 | ||
обычно так не работают в питоне, но если уж не в терпеж:
ессно надо протестить на всякие бяки.... |
Автор: WolfAlone 18.1.2011, 12:16 |
Подскажите пожалуйста, как правильно решать подобную задачу? В своё время работал с такой штукой на PHP как CodeIgniter, там очень удобно прасится URL. Выглядит это примерно так: example.com/class/func/param1/param2/param3/etc где: example.com - адрес сайта class - пользовательский контроллер (класс) func - функция в этом классе (метод класса) param 1-3 (всё остальное) - входные параметры для этой функции Задумка мне очень понравилась, решил сделать нечто аналогичное на Python... |
Автор: WolfAlone 19.1.2011, 22:50 |
Писал я тут писал... Много написал ![]() av0000, спасибо огромное, Вы натолкнули меня на верное направление! bilbobagginz, премного благодарен! Из двух примеров выше сейчас буду пробовать собрать 1 ![]() |
Автор: WolfAlone 19.1.2011, 23:16 | ||
Остался пожалуй только 1 вопрос: Как защититься от "кул хацкеров", т.е. проще говоря как "найти" класс, зная его имя записанное в строковую переменную без eval() или как проверить, то ли (что нужно/можно) выполняется в eval(), что может выполняться? Если создать список с допустимыми значениями - это будет надёжной защитой? Я немного поясню:
|
Автор: av0000 20.1.2011, 11:33 | ||||||
Ну, во-первых я сильно не люблю пользоваться eval по двум причинам - выжирание памяти "как под целый питон" на время запуска (можно сказать, что на вызов eval "запускается" новый интерпретатор) и как раз эта дыра с запуском произвольного кода. решение "раз" - сделать словарь с именами классов и классами и искать допустимые только в нем:
решение "два" если охота таки использовать eval:
"фишка" второго решения - во-первых принудительно создаём экземпляр внутри eval - какую-то часть "мусора" удастся этим отсечь, во-вторых - ограничиваем список того, чем может пользоваться eval (см. доку на её параметры) НО! нормального сандбокса таким ограничением не сделать :( и при желании юзер может ввести что-то типа "import os; os.system('rm -rf /')" и кому-то будет очень весело ;) PS: прошу не воспринимать строку с import буквально ![]() PPS: а заполнять словарь из первого примера можно по аналогии с тему куском кода, что я привёл раньше
|
Автор: stalk13 14.5.2011, 16:04 | ||
Я бы в этом случае использовал декораторы:
|