需要
我々は、しばしば。行うパラメータの交換を容易にするために、データテンプレートが、このような$名または{{名前}}又は%(名)Sなどのプレースホルダ変数を、埋め込まれた事前定義する必要がある
。これは、文字列形式またはテンプレートの使用を必要としますエンジン(例えばJinja2のように)あなたが指定した場所にテンプレートにデータのグループを交換できるようになります。
Pythonは三つの一般的な方法があるの書式文字列が付属しています:
- %sのか%(名)■
'姓名: %s, 年龄: %d' %('Kevin', 21)
'姓名: %(name)s, 年龄: %(age)d' % {'name':'Kevin', 'age': 21}
- .format構文を使用します。
'姓名: {}, 年龄: {}'.format('Kevin', 21)
'姓名: {name}, 年龄: {age}'.format(name='Kevin', age=21)
- [テンプレートとsafe_substitute()
from string import Template
Template('姓名: $name, 年龄: $age').safe_substitute(name='Kevin', age=21)
変数のレンダリングに加えて、このようなJinja2のような特定のテンプレートのレンダリングエンジンは、このような次のように簡単な方法を使用して、場合やループ反復し、フィルタ等のために決定するなど、より多くの機能をサポートしています。
from jinja2 import Template
Template('姓名: {{ name }}, 年龄: {{age}}').render(name='Kevin', age=21)
YAMLファイルの組み込み変数をレンダリングするための型、または{%}はいくつかの問題になります使用して、私たちは、区切り文字としてここに$を使用することを選択し、時には我々は、デシリアライズに変数置換する必要があり、その後、リスト/辞書の種のために代替的に埋め込まれた変数は、例えば、そのようなリストがあります。
s = ['性别: $2 年龄: $3\n$a', '$1', {"say": "$a"}]
私たちは、これでデータを交換する必要がある$1
最初の引数を表す、$a
代表的なパラメータは、a
その後、使用safe_subtitute()
ので、ここでは、より多くのトラブルを方法を簡単な道具である
$変数置換法
プロパティ
- サポートは、
$1
最初のパラメータを置き換えること、および$a
パラメータを置き換えますa
- サポート辞書/リスト/元祖、およびネストされた辞書/変数リストを交換してください
- これは、指定された区切り文字のデフォルトをサポートしています
$
- これは、複数行のテキスト置換をサポートしています
- 完全に交換しないで、元の値を保持し、与えられていない場合
原則
カスタムハンドラを交換するためのライブラリのサポートの再Pythonの正規サブ方法
re.sub(匹配表达式, 替换值或替换处理函数, 原始文本, re.M) # 使用re.M 支持跨行
実装コード
import re
import json
def render(origin, *args, delimiter="$", **kwargs): # 支持修改delimiter定界符
patten = r'\{}(?P<var>[\w|_]+)'.format(delimiter)
def repl_func(matched): # 自定义re.sub使用的替换方法
var = matched.group('var')
if var.isdigit(): # 如果是数字, 则从args中替换
index = int(var) - 1
if index < len(args):
return args[index]
else:
return "{}{}".format(delimiter, var) # 无替换参数则返回原值
else:
return kwargs.get(var, None) or "{}{}".format(delimiter, var) # 返回kwargs参数中值 or 原值
if isinstance(origin, str):
return re.sub(patten, repl_func, origin, re.M)
elif isinstance(origin, (dict, list)): # 使用json.dumps转为字符串, 替换,然后重新转为dict/list
return json.loads(re.sub(patten, repl_func, json.dumps(origin), re.M))
else:
if isinstance(origin, tuple):
return tuple(json.loads(re.sub(patten, repl_func, json.dumps(origin), re.M))) # 转换后重新转为tuple
if __name__ == '__main__':
s = ['性别: $2 年龄: $3\n$a', '$1', {"say": "$a"}]
print(render(s, 'kevin', 'male', '20', a="hello, world!"))
出力:
['性别: male 年龄: 20\nhello, world!', 'kevin', {'say': 'hello, world!'}]