Использование методов locals() и format() для строк: существуют ли какие-либо оговорки?
Существуют ли какие-либо недостатки, оговорки или предупреждения о плохой практике об использовании следующего шаблона?
def buildString(user, name = 'john', age=22):
userId = user.getUserId()
return "Name: {name}, age: {age}, userid:{userId}".format(**locals())
У меня был очень повторяющийся код генерации строки для записи, и у меня возникло соблазн использовать это, но что-то об использовании locals()
делает меня неудобным. Есть ли в этом опасность неожиданного поведения?
Изменить: контекст
Я обнаружил, что постоянно пишу такие вещи, как:
"{name} {age} {userId} {etc}...".format(name=name, age=age, userId=userId, etc=etc)
Ответы
Ответ 1
Теперь есть официальный способ сделать это, начиная с Python 3.6.0: форматированные строковые литералы.
Это работает так:
f'normal string text {local_variable_name}'
Э.Г. вместо них:
"hello %(name)s you are %(age)s years old" % locals()
"hello {name}s you are {age}s years old".format(**locals())
"hello {name}s you are {age}s years old".format(name=name, age=age)
просто сделай это:
f"hello {name}s you are {age}s years old"
Вот официальный пример:
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'
Ссылка:
Ответ 2
Если строка формата не предоставляется пользователем, это использование в порядке.
format
предпочтительнее использования старой %
для замены строки.
locals
встроен в Python, и его поведение будет надежным.
Я думаю, что locals
делает именно то, что вам нужно.
Просто не изменяйте словарь от локальных жителей, и я бы сказал, что у вас довольно хорошее решение.
Если строка формата предоставлена пользователем, вы подвержены атакам при инъекциях всякого рода неприятностей.
Ответ 3
Я регулярно занимаюсь этим. Единственная проблема, с которой я столкнулся, заключается в том, что PyFlakes будет жаловаться на неиспользуемые переменные, когда я это сделаю.
Ответ 4
Ответ до Python 3.6
Это очень старо, но если вы обнаружите, что используете .format
, то единственное предостережение, с которым я столкнулся при передаче в **locals
, заключается в том, что если вы не определили эту переменную где-либо, она сломается. Явное указание передаваемых переменных позволит избежать этого в большинстве современных IDE.
foo = "bar"
"{foo} and {baz} are pair programming".format(**locals())
<exception occurs>