Давайте рассмотрим это одно за другим:
eval('"' + s.replace('(', '"+("').replace(')', '")[::-1]+"') + '"')
Это фактически то же самое, что и следующее (что может облегчить понимание):
code = '"' + s.replace('(', '"+("').replace(')', '")[::-1]+"') + '"'
eval(code)
То же самоеas:
innerCode = s.replace('(', '"+("').replace(')', '")[::-1]+"')
code = '"' + innerCode + '"'
eval(code)
innerCode
выполняет там простые манипуляции со строками:
- Заменить
(
на "+("
- Заменить
)
на ")[::-1]+"
Итак, взяв пример (bar)
в качестве примера, вы получите следующий результат: "+("bar")[::-1]+"
Если вы добавите кавычки снова, вы получите следующую строку:
""+("bar")[::-1]+""
= ("bar")[::-1]
= "bar"[::-1]
То, что [::-1]
делает со строкой, переворачивает ее, по сути, повторяя ее сзади (это то, что делает -1
):
>>> 'foo'[::-1]
'oof'
>>> 'bar'[::-1]
'rab'
Когда этот результирующий код затемвыполненный с eval
, вы получите свой результат.
Давайте рассмотрим другой пример: foo(bar)baz(blim)
.После замены скобок вот что вы получите:
foo"+("bar")[::-1]+"baz"+("blim")[::-1]+"
Добавьте кавычки и упростите их, и вы получите:
"foo"+("bar")[::-1]+"baz"+("blim")[::-1]+""
= "foo" + ("bar")[::-1] + "baz" + ("blim")[::-1]
= "foo" + "bar"[::-1] + "baz" + "blim"[::-1]
Когда вы выполните это, вы получите "foo" + "rab" + "baz" + "milb"
.
Обратите внимание, что хотя это работает для решения задачи, использование eval
на самом деле очень плохая идея.eval
выполняет любой код, а не только конкатенацию строк и обращение строк.Поэтому, если вы берете данные из источника, которому вы не доверяете вслепую, злоумышленники могут использовать это для выполнения неверного кода.
Гораздо лучше реализовать это поведение без eval
, что не так.t , что сложно, поскольку вы все-таки просто манипулируете строкой.
Например, используя регулярные выражения для быстрого поиска скобок:
import re
def reverseInParentheses(s):
for m in re.findall('\((.*?)\)', s):
s = s.replace('(' + m + ')', m[::-1])
return s
>>> reverseInParentheses("(bar)")
'rab'
>>> reverseInParentheses("foo(bar)baz")
'foorabbaz'
>>> reverseInParentheses("foo(bar)baz(blim)")
'foorabbazmilb'
>>> reverseInParentheses("foo(bar(baz))blim")
'foozab(rab)blim'
Примечаниечто это не правильно работает для последнего примера, который имеет вложенные скобки.В таких случаях гораздо лучше использовать правильный синтаксический анализатор, например pyparsing
.Это более подробно описано в этом ответе на другой вопрос .
Я бы настоятельно рекомендовал вам не использовать eval
здесь, хотя даже если это работает для вашего случая.