Python / str() / オブジェクトを文字列に変換する方法
Pythonのstr()は、オブジェクトを読みやすい文字列として表現します。数値と文章を連結したり、文字列表現を変数に保存したりするときに使い、元のオブジェクトの型を変更するのではなく文字列を返します。バイト列のデコードやJSON生成には目的に合う処理が必要です。
基本的な変換と戻り値の型
str(object)は数値や真偽値などからstrを返し、引数なしのstr()は空文字列を返します。通常はオブジェクトの__str__()による表現が使われ、独自クラスで表示を定義できます。対応形式はstr型の公式リファレンスで確認できます。
例にはPython 3と標準ライブラリだけを使います。次の全体をUTF-8のstr_example.pyに保存し、端末でpython str_example.pyを実行します。環境によってはpython3です。以降の例も独立しているため、同じファイルの内容を置き換えて実行できます。
number = 42
text = str(number)
print(number, type(number).__name__)
print(text, type(text).__name__)
print("ID-" + text)
print(repr(str()))
print(str(None))
期待される出力は次のとおりです。
42 int
42 str
ID-42
''
None
表示はどちらも42ですが型が異なります。numberは整数のまま、textだけが文字列です。repr()で示した''は長さ0の文字列で、str(None)は空ではなくNoneという文字を返します。
数値変換と表示書式を区別する
str()は数値の基本表現を返し、小数点以下の桁数や通貨書式は指定しません。2桁表示などの規則が必要ならf文字列などの書式指定を使います。
price = 12.5
print(str(price))
print(f"{price:.2f}")
print("price=" + str(price))
12.5
12.50
price=12.5
12.50は小数点以下2桁で表示した文字列です。元のpriceは変わりません。表示の丸めと数値計算の精度は別の問題です。
bytesから文字を得るにはデコードする
bytesはバイトデータ、strはUnicode文字列です。str(raw)だけではバイトオブジェクトの表現になります。元の文字を得るには実際のエンコーディングを指定し、decode()またはstr(raw, encoding)を使います。
raw = "café".encode("utf-8")
print(str(raw))
print(raw.decode("utf-8"))
print(str(raw, "utf-8"))
b'caf\xc3\xa9'
café
café
最初の行のbと逆スラッシュ表記はバイトの表現です。後の2行がUTF-8でデコードした文字列です。ファイルや応答が別の方式なら、その方式を指定します。エラーを消すためだけのerrors="ignore"は一部データを失う可能性があります。
str()・repr()・JSONの選び方
str()は読みやすい表示、repr()は開発中にオブジェクトの表現を確認するために主に使います。ただしrepr()もすべてのオブジェクトを復元できるコードにする保証はありません。データ交換にはjson.dumps()でJSONを生成します。JSONはJavaScript Object Notationの略で、標準的なテキストデータ形式です。
import json
data = {"active": True, "count": 0}
print(str(data))
print(json.dumps(data))
print(str("hello\nworld"))
print(repr("hello\nworld"))
{'active': True, 'count': 0}
{"active": true, "count": 0}
hello
world
'hello\nworld'
辞書のstr()はPythonの引用符やTrueを使うため、そのままJSONとは考えません。文字列の改行はstr()で表示すると実際の改行になり、repr()では\nのような表現になります。
Noneだけを空文字列にする
欠損値Noneだけを空にするならis Noneで判定します。str(value or "")では0やFalseまで空になり、値の意味を失うことがあります。
for value in (None, 0, False):
text = "" if value is None else str(value)
print(repr(text))
''
'0'
'False'
連結とデコードのエラーへの対応
文字列と数値を直接+で連結するとTypeErrorになります。数値をstr()に渡すかf文字列を使います。指定エンコーディングでバイト列を解釈できないとUnicodeDecodeErrorになるため、元の文字コードとデータの完全性を確認します。
try:
print("ID-" + 42)
except TypeError:
print("TypeError")
try:
str(b"\xff", "utf-8")
except UnicodeDecodeError:
print("UnicodeDecodeError")
TypeError
UnicodeDecodeError
最後の例は種類を確認するため例外を捕捉しています。独自の__str__()が不正な型を返す場合や内部で例外を出す場合も変換は失敗するので、すべてを連結エラーと決めつけないようにします。




