0

I have a prepared string, e.g. my_string = 'My name is {name}.'

and I have dictionary of kwargs, such as:

format_kwargs = {
    'name': 'John',
    ...
}

So that I can format the string in this manner: my_string.format(**format_kwargs)

That is all good. The problem is that I want to determine what keys are in the string, so that I do not calculate the kwargs needlessly. That is, I have a set of keywords used in these strings by default, but not all of them are used in all strings. They are basically regular messages shown to user, such as '{name}, you account was successfully created!'.

I want to do something like:

format_kwargs = {}

if 'name' in <my_string.keys>:
    format_kwargs['name'] = self.get_user().name
if '...' in <my_string.keys>:
    format_kwargs['...'] = some_method_...()

my_string.format(**format_kwargs)

How do I retrieve the keys?

EDIT:

a simple if 'name' in my_string does not work because that would also match something like {parent_name} or 'The name change was not successful.'

emihir0
  • 1,200
  • 3
  • 16
  • 39
  • 1
    It is no problem to supply more keywords than present in the format string. – Klaus D. Oct 18 '17 at 10:15
  • what is `self.get_user()`? – RomanPerekhrest Oct 18 '17 at 10:15
  • 1
    Are those values so *very expensive* to calculate that it's worth it? – Jon Clements Oct 18 '17 at 10:16
  • 1
    What's wrong with `if '{name}' in my_string:`? However, as Jon implies, it may be more efficient to simply create the whole dict than to perform all those `if` tests. – PM 2Ring Oct 18 '17 at 10:16
  • 1
    Possible solutions can be found in [this related question](https://stackoverflow.com/questions/25996937/how-can-i-extract-keywords-from-a-python-format-string). In this particular case however, an alternative solution would be to implement a dict-like class that computes the values on demand. – Aran-Fey Oct 18 '17 at 10:18
  • which keys? keys of my_string or format_kwargs? how can my_string.keys even have keys, if my_string is not a dictionary? – Eamonn Kenny Oct 18 '17 at 10:20
  • Some of the lookups can be quite expensive, yes. However, silly me. I didn't think about `if '{name}' in my_string:`... of course that works too. – emihir0 Oct 18 '17 at 10:25
  • OTOH, the simple `if '{name}' in my_string:` won't work if your format specs include anything more than the variable name. In that case, it makes sense to use a `string.Formatter`. – PM 2Ring Oct 18 '17 at 10:30
  • And rather than creating a whole bunch of instances of `string.Formatter`, just create a single instance and use it on all the strings, eg `parse_format = string.Formatter().parse` – PM 2Ring Oct 18 '17 at 10:37

1 Answers1

0

Use string.Formatter

from string import Formatter
s = 'Hello {name}. Are you {debil_status}'
keys = [i[1] for i in Formatter().parse(s)]
print keys

>>> ['name', 'debil_status']
Kamo Petrosyan
  • 214
  • 1
  • 9