リファクタリングをPythonで実践!基本手法とコード例・注意点まで
- 1.Pythonのprintとは?
- 2.printで出力してみよう
- 3.出力結果が改行されないようにするには?
- 4.formatメソッドを使う方法
- 5.f文字列を使う方法
- 6.書式指定文字列
- 7.Pythonでprintを使う際の注意点とコツ
1.Pythonのprintとは?
Pythonのprint関数は、開発時、運用時に必ずと言っていいほど使用する関数です。
・文字列
・数値
・真偽値(True、False)
を画面(ターミナル、コンソール)に出力する役割があります。
数値や文字列、真偽値は変数に入っていてもよく、またリストやタプルや辞書の変数もそのまま出力できるので、変数の値を確かめるのに便利です。このことからデバッグでよく使われます。
また、実行時にどこまで処理が進んでいるのかを知らせる目的でも、print関数は使われます。
①Pythonのprintの基本的な使い方・構文
それではサンプルコードを交えて解説していきます。なお、この記事ではサンプルコードは全て対話モードで実行します。print関数の基本的な構文は以下のようになります。
例えば文字列’abcde’を画面に出力するとしたら
print('abcde')
abcde
と書きます。printは関数なので、出力したい値を必ず()で囲ってください。
②Python2とPython3での違い
printは関数と書きましたが、実は、関数なのはPython 3系での話なのです。Python 2系では、printは「文」です。
つまり、()を使いません。
‘abcde’を画面に出力するprintは、Python 2系なら
print 'abcde'
abcde
となります。
とは言え、Python 2系から3系への移行が推奨されていますし、また、今現在Python 2系を使う新規開発はほぼありません。だからこの記事でも、Python 3系のみを使うこととして、printが関数の場合のみ説明します。
また、詳しくは後述しますが、Python 3.6以降では、f文字列という簡単な書き方で出力を整形する機能が追加されています。これはprintではなく文字列型への機能追加ですが、print関数でf文字列を使うと便利です。
2.printで出力してみよう
①文字列の出力
繰り返しになりますが、’abcde’を出力するには
print('abcde')
abcde
マルチバイト文字も使えます。文字列型に代入できる文字なら全て出力できます。
print('あいうえお')
あいうえお
あいうえお
複数の文字列を並べて出力することもできます。
print('a','b','c')
a b c
デフォルトでは半角スペースで区切られますが、
sep
を使うと、区切り文字を指定することができます。
print('a', 'b', 'c', sep='-')
a-b-c
②数値の出力
1を出力してみましょう。
print(1)
1
ただ数値を書けばいいだけです。少数部がある数値の場合
print(1.00)
1.0
print(1.32000)
1.32
と、最後の0は出力されず、小数点以下が全て0の場合は小数点第一位だけが出力されます。文字列と同じく、複数の数値を並べて表示することもできます。
print(1, 2.3, 4)
1 2.3 4
また、sepを使うこともできますよ。
print(1, 2.3, 4, sep='-')
1-2.3-4
文字列を混在させることも可能です。
print('コーラは', 58, '円')
コーラは 58 円
③リストの出力
ただリストを渡せばいいだけです。
print([1, 2, 3])
[1, 2, 3]
ただこれだと、「[]」で囲われて、「,」で区切られています。囲いを無くして区切りを半角スペースにするには「*」を使います。
print(*[1, 2, 3])
1 2 3
sepを使うこともできます。
print(*[1, 2, 3], sep='-')
1-2-3
*を使わずにsepを使っても、「区切り」はリストがまるごと「区切り」になりますから、意味がないことに注意してください。
print([1, 2, 3], sep='-')
[1, 2, 3]
④辞書の出力
辞書も、ただ辞書を渡せばいいだけです。
print({'a':1, 'b':2, 'c':3})
{'a': 1, 'b': 2, 'c': 3}
辞書の前に「*」を付けると、キーだけを半角スペースで区切って出力します。
print(*{'a':1, 'b':2, 'c':3})
a b c
キーだけ出力されて何の役に立つのか、と思うかもしれませんが、キーの一覧を取得したいときに使います。もちろんsepを使うこともできます。
print(*{'a':1, 'b':2, 'c':3}, sep='-')
a-b-c
⑤変数の出力
さて、こちらがprint関数の本番です。変数の値を出力する方法について見ていきます。
基本的には
a = 0
print(a)
0
なのですが、複数の変数を出力することは開発の現場ではよく行います。たとえば下記のようなコードです。
a = 0
b = 1
print(a, b)
0 1
ただこれだとどの変数がどの値なのか分からないので、以下のように書くことが普通です。
a = 0
print('a:', a)
a: 0
b = 1
print('a:', a, 'b:', b)
a: 0 b: 1
改行文字を入れるともっと見やすいですね。
a = 0
b = 1
print('a:', a, '\nb:', b)
a: 0
b: 1
リストや辞書の変数も同じです。
l = [1, 2, 3]
print(l)
[1, 2, 3]
dict = {'a':1, 'b':2, 'c':3}
print(dict)
{'a': 1, 'b': 2, 'c': 3}
printは関数なので、「()」の中はPythonで書ける文はなんでも書けます。
c = 3
d = 4
print(c + d)
7
このコートでは、cの値とdの値が出力されるのではなく、c+dの値が出力されることに注意してください。この性質を利用すると、文字列を連結して出力することができます。
s = 'abcde'
print('s:' + s)
s:abcde
ただしこの+はPythonの式なので、文字列と数値の連結はできません。
s = 'abcde'
v = 1
print(s + v)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
文字列と数値を連結する際は、str関数を使い数値を文字列に変換しましょう。
s = 'abcde'
v = 1
print(s + str(v))
abcde1
ここは実際の開発でケアレスミスをしやすいポイントなので注意してください。
3.出力結果が改行されないようにするには?
出力結果を改行しないためには、endを使います。endとはprint関数の出力の後に出力する文字列を指定するものです。デフォルトが「\n」になっていますので、print関数の出力はデフォルトでは改行されてしまうのです。
a = 0
b = 1
print ('a:' , a, 'b:', b, end='')
a: 0 b: 1
これは例えばfor文の中で使います。
for a in range(10):
print(a, ' ', end='')
print('\n')
0 1 2 3 4 5 6 7 8 9
4.formatメソッドを使う方法
①formatメソッドとは
formatメソッドとは、正確にはprint関数の機能ではなく、Pythonの文字列型の機能です。formatメソッドを使うと自然な書き方で変数の値を表示することができます。このことから、print関数の機能を強化するために使用されます。
②formatメソッドとprintの合わせ技
一番簡単な書き方は
a = 0
b = 1
print('aは{}, bは{}'.format(a, b))
aは0, bは1
と、ただ{}を使い、文字列のあとに
.format
を付けて{}の中に値を出力したい変数を順番通りに並べて書く、という書き方です。しかしこの場合、どの変数の値がどこに出力されるか分からないので、より分かりやすいコードにするために、
a = 0
b = 1
print('aは{0}, bは{1}'.format(a, b))
aは0, bは1
とインデックスを指定したり(ゼロから始まります)、
a = 0
b = 1
print('aは{v1}, bは{v2}'.format(v1=a, v2=b))
aは0, bは1
代入用の変数をつかって受け渡したりもします。インデックスや代入用の変数を使うと、同じ変数の値を複数回出力できます。
a = 3
print('{0},{0},{0}'.format(a))
3,3,3
5.f文字列を使う方法
①f文字列とは
しかしformatメソッドでも問題があります。文字列の後に出力する変数を書くので、どの変数が出力されるのか一目で分からないのです。この問題を解決するため、Python 3.6でf文字列が導入されました。f文字列を使うと、どの場所にどの変数の値が出力されているのか一目で分かります。
②f文字列とprintの合わせ技
f文字列は、文字列の前にfと書き、{}の中に値を表示させたい変数名を書くだけです。
a = 0
b = 1
print(f'aは{a}, bは{b}')
aは0, bは1
もちろん同じ変数も書けます。
a = 3
print(f'{a},{a},{a}')
3,3,3
6. 書式指定文字列
formatメソッドもf文字列も、数値の出力のときに、{}の中で書式指定文字列が使えます。書式指定文字列は、
a = 3
print(f'{a:03}')
003
のように、「:」で区切って「:」の右側に書きます。書式指定文字列はミニ言語です。正規表現と同じようなものです。書式の指定には以下のようなものがあります。
<:左寄せ
^:中央寄せ
>:右寄せ
0:ゼロ埋め
+:プラスの時も符号表示
b:2進数表記
o:8進数表記
x:16進数表記(a~fは小文字)
X:16進数表記(A~Fは大文字)
これらの書式の後に
桁数
の数値を書きます。
また、桁数が指定できない
.数値f:小数点以下の桁数
,:桁区切りを表示
もあります。
例を見ていきましょう。
a = 12345.67
print(f'{a:<10}')
12345.67
print(f'{a:^10}')
12345.67
print(f'{a:>10}')
12345.67
print(f'{a:010}')
0012345.67
print(f'{a:+10}')
+12345.67
print(f'{a:,}')
12,345.67
print(f'{a:.5f}')
12345.67000
a=255
print(f'{a:b}')
11111111
print(f'{a:o}')
377
print(f'{a:x}')
ff
print(f'{a:X}')
FF
7.Pythonでprintを使う際の注意点とコツ
さて、formatメソッドには次の二つの問題点があります。
- 書式指定と変数が離れているので、順番を入れ替えたりする修正を行うときに、書式指定と変数の両方を修正しなければならず、修正箇所が単純に2倍になる
- {}と変数が離れているので、一目でわかりにくく、更に、冗長でうるさい感じになる
これらの問題点があるため、print関数を使いこなそうと思ったら、一般にはf文字列の方を使うと良いでしょう。
また、単純にデバッグ目的のためだけにprint関数を挿入したなら、本番リリース前に必ずコメントアウトしてください。削除してしまうのはおすすめできません。一般的にprint関数を使ってデバッグする箇所はロジックが割合入り組んでいる重要な箇所で、コードの修正のときに同じデバッグが必要になる可能性が高いからです。
変数だけを書いてprint関数を使うこともできますが、文章中で触れた通り、変数名も合わせて出力することを強くお勧めします。
また運用の際に、システムからの報告だけのためにprint関数を使うときですが、どの関数のどの行なのかも合わせて出力するべきです。そうしないと、いったい何の報告なのか後から分からなくなります。
Pythonを極めていくと、print関数の代替としてログを出力したりするようになります。大規模開発ではたいていログを出力しています。各種フレームワークにもログ出力の機能があるものがあります。
そうした場合、print関数は本当に開発時の小さなデバッグのためだけに使ってください。ログに出力する内容は慎重に吟味しないとログが膨大になって解析できなくなってログの意味をなくしますが、それでも、ログ出力がある場合には基本的にはログに出力するべきです。ログは全ての記録を保存しておくためにあります。