Я бы придерживался Zen of Python , в частности, "Явное лучше, чем неявное" и "Количество читабельности".
Так что хорошо бы иметь ваши функции в виде читаемых строк, определяющих лямбда-выраженияИдея, хотя, из соображений безопасности, вызов eval
для загруженного строкового представления лямбда может не быть.Это опять-таки зависит от того, у кого есть доступ к файлу изменений и в какой системе они запущены.
В общем случае вам не нужно слишком сильно беспокоиться, если кто-то может (не случайно) внедрить что-либо, что приведет к рекурсивному удалению всех файлов насистема, если у них есть права доступа для входа в систему, с которыми они могут сделать это в любом случае.Однако, если, например, программное обеспечение работает в удаленной системе, и эти файлы можно редактировать через какой-либо веб-интерфейс, или если изменения в файле могут быть сделаны кем-то, кроме человека, использующего эти файлы, это то, что вы должны принять во внимание.
Если лямбды приходят из фиксированного набора, вы можете просто использовать их строковое представление в качестве поиска:
lambdas = {}
for l in [
'lambda x,y: x+y',
'lambda x: (x**3)/2',
# some more
]:
lambdas[l] = eval(l)
Затем вы можете использовать строку, загруженную из вашей конфигурации YAML, чтобы получить реальную лямбду иэту строку нельзя изменить, так как она должна соответствовать доступному набору лямбд, которые вы указали.Конечно, вы можете загрузить реальные лямбда-строки из файла, который можете изменить только вы, вместо того, чтобы жестко кодировать их в исходном коде.
Это IMO более явный, чем дамп реальной лямбды, в результате чего YAML выглядит следующим образом:
!!python/name:__main__.%3Clambda%3E
, что в любом случае требует небезопасной загрузки документа YAML.
Есливам нужно быть более гибким, чем использовать предопределенные лямбды, но вы не хотите небезопасно использовать eval
, тогда другой возможностью является использование модуля AST в Python.Этот модуль позволяет безопасно вычислять унарные и двоичные операторы, но может быть расширен для обработки только тех функций (например, некоторых математических функций), которые вы хотите разрешить в своей лямбде.Я проделал аналогичное расширение в своем модуле нотации объектов Python ( PON ), добавив datetime и возможности отступления к оцененному входу AST.
Что-то ещеИМО должен улучшить свой YAML.Вместо использования gene1
, gene2
в качестве ключей в отображении используйте последовательность и отметьте элементы:
pre_init_gene:
- !Gene 1.0
- !Gene 1.0
- !Gene 1.0
или, альтернативно, пометьте последовательность:
pre_init_gene: !Genes
- 1.0
- 1.0
- 1.0
Ваши лямбдыу меня та же «проблема», и я бы сделал что-то вроде:
obj_funcs:
- !Lambda 'x, y: x+y'
- !Lambda 'x: (x**3)/2'
, где объект, реализующий from_yaml
classmethod
для тега !Lambda
, прозрачно выполняет оценку eval или AST.