Вот метод, который используется в Commerce SagePay и в модулях Drupal Commerce Paypoint [dr1]], которые в основном сравнивают document.location.href
со старым значением, сначала загружая свой собственный iframe, затем внешний.
Так что в основном идея состоит в том, чтобы загрузить пустую страницу в качестве заполнителя с собственным кодом JS и скрытой формой. Затем родительский JS-код отправит эту скрытую форму, где ее #action
указывает на внешний iframe. Когда происходит перенаправление / отправка, код JS, который все еще работает на этой странице, может отслеживать ваше значение document.location.href
.
Вот пример JS, используемый в iframe:
;(function($) {
Drupal.behaviors.commercePayPointIFrame = {
attach: function (context, settings) {
if (top.location != location) {
$('html').hide();
top.location.href = document.location.href;
}
}
}
})(jQuery);
И здесь JS используется на родительской странице:
;(function($) {
/**
* Automatically submit the hidden form that points to the iframe.
*/
Drupal.behaviors.commercePayPoint = {
attach: function (context, settings) {
$('div.payment-redirect-form form', context).submit();
$('div.payment-redirect-form #edit-submit', context).hide();
$('div.payment-redirect-form .checkout-help', context).hide();
}
}
})(jQuery);
Затем на временной пустой целевой странице вам нужно включить форму, которая будет перенаправляться на внешнюю страницу.
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = string.replace('@', '')
for i in mydict:
string = string.replace(i, str(mydict[i]))
print(string)
print(eval(string))
вывод:
10 + (5 + 1) / 10 * 1.2
10.72
Я думаю, что вам нужно захватить регулярное выражение @
+ буквы / цифры / подчеркивание, которое равно "@(\w+)
(соответствует @
, затем 1 или более букве / цифре / подчеркиванию и создать группу с ними), поданным на функция замены
import re
mydict = {'Cost1' : 10, 'Cost2' : 5, 'Cost3' : 1, 'Revenue1' : 10}
string = '@Cost1 + (@Cost2 + @Cost3) / @Revenue1 * 1.2'
expression = re.sub("@(\w+)",lambda m : str(mydict.get(m.group(1),0)),string)
результат:
'10 + (5 + 1) / 10 * 1.2'
Этот метод очень эффективен, потому что он использует поиск в словаре вместо циклических, чтобы заменить и создать столько строк как есть переменные.
обратите внимание, что любая неизвестная переменная выдает 0. Если вы не хотите, чтобы это использовалось, используйте mydict[m.group(1)]
, чтобы вызвать ошибку ключа.
lambda
также не является обязательным. Вместо этого вы можете написать реальную функцию, если она принимает объект match
в качестве входных данных и возвращает строку в качестве выходных данных:
def repfunc(m)
return str(mydict.get(m.group(1),0))
re.sub("@(\w+)",repfunc,string)
(поэтому мы конвертируем в строку после получения значения)
Если у вас есть это выражение, вы можете применить оценщик (eval
является самым простым, но менее безопасным, ast.literal_eval
не будет работать, потому что он не поддерживает операции, но есть и другие, например, [ 1111] сторонний модуль (которому можно подать список переменных, который еще больше упростит ответ), или другие примеры здесь: Оценка математического выражения в строке )