2018年01月28日

言語処理100本ノックでPython入門 #07 - 文字列のフォーマット

   このエントリーをはてなブックマークに追加 Clip to Evernote

言語処理100本ノック 2015
の問題07を解きました。

■ 問題
07. テンプレートによる文生成

引数x, y, zを受け取り「x時のyはz」という文字列を返す関数を実装せよ.さらに,x=12, y="気温", z=22.4として,実行結果を確認せよ.


■ 書いたコード


3つの方法で、実装してみました。
from string import Template

def formatText(x, y, z):
    return "{hour}時の{target}は{value}".format(hour=x, target=y, value=z)

def formatText2(x, y, z):
    s = Template('$hour時の$targetは$value')
    return s.substitute(hour=x, target=y, value=z)

def formatText3(x, y, z):
    return '%s時の%sは%s' % (x, y, z)

def main():
    x = 12
    y = "気温"
    z = 22.4
    print(formatText(x, y, z))
    print(formatText2(x, y, z))
    print(formatText3(x, y, z))

main()

■ 実行結果
12時の気温は22.4
12時の気温は22.4
12時の気温は22.4
3つとも同じ結果になりました。

■ 今回学んだこと


文字列のフォーマット その1
def formatText(x, y, z):
    return "{hour}時の{target}は{value}".format(hour=x, target=y, value=z)
C#の挿入文字列に似ています。でも、以下のようには書けません。
    return "{x}時の{y}は{z}".format(x, y, z)

文字列のフォーマット その2

Templateクラスを使うと、以下のように書けます。
from string import Template
...

def formatText2(x, y, z):
    s = Template('$hour時の$targetは$value')
    return s.substitute(hour=x, target=y, value=z)

文字列のフォーマット その3

以下のような書き方もあるようです。すこしC言語っぽいです。
def formatText3(x, y, z):
    return '%s時の%sは%s' % (x, y, z)



変数のスコープに関して
def formatText(x, y, z):
    return "{hour}時の{target}は{value}".format(hour=x, target=y, value=z)

x = 12
y = "気温"
z = 22.4
print(formatText(x, y, z))

と書いたら、関数の定義している行で、
W0621:Redefining name 'x' from outer scope (line xx)

のような警告が出ました。

グローバルの変数と関数の仮引数の名前が同じだと、関数の中で、グローバル変数が参照できなくなるよ、という警告っぽいです。
確かにその通り。

なので、以下のようにmain関数を定義することで、回避しました。
def main():
    x = 12
    y = "気温"
    z = 22.4
    print(formatText(x, y, z))

main()