序章
string モジュールには Template クラスがあり、マッピング オブジェクトを使用して文字列を置換できます。たとえば、次のようになります。
>>> string.Template('var is $var').substitute({'var': 1})
'var is 1'
たとえば、マッピングにない要素を置換しようとすると、substitute メソッドは KeyError 例外を発生させることがあります。
>>> string.Template('var is $var and foo is $foo').substitute({'var': 1})
KeyError: 'foo'
$
または、テンプレート文字列が無効な場合 (たとえば、文字の後にスペースが続く場合)、ValueError が発生する可能性があります。
>>> string.Template('$ var is $var').substitute({'var': 1})
ValueError: Invalid placeholder in string: line 1, col 1
問題
テンプレート文字列とマッピングが与えられた場合、テンプレート内のすべてのプレースホルダーが置換されるかどうかを判断したいと思います。このために、置換を行い、KeyError 例外をキャッチしようとします。
def check_substitution(template, mapping):
try:
string.Template(template).substitute(mapping)
except KeyError:
return False
except ValueError:
pass
return True
ただし、テンプレートが無効で ValueError が発生した場合、後続の KeyError がキャッチされないため、これは機能しません。
>>> check_substitution('var is $var and foo is $foo', {'var': 1})
False
>>> check_substitution('$ var is $var and foo is $foo', {'var': 1})
True
しかし、ValueErrorsは気にしません。では、この問題に対する正しいアプローチは何でしょうか?