質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

Q&A

解決済

1回答

6386閲覧

Python3のUnicodeEncodeErrorについて

teityura

総合スコア84

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

0グッド

0クリップ

投稿2018/11/11 09:29

編集2018/11/11 11:00

下記を実行し、英数字をinputすれば問題なく動作するのですが、
日本語文字列を入れると、
UnicodeEncodeError: 'utf-8' codec can't encode characters in position [txt変数に格納された文字列の該当位置開始位置から終了位置]: surrogates not allowed

type(txt): <class 'str'>
type(answer): <class 'str'>
typeを見ても、同じstr型のクラスで問題なさそうに思えます。
どう解釈されて、なぜエラーになっているのでしょうか。

bash

1# エラー内容 ↓↓↓↓↓ 2キリンは大昔から__複数名詞__の興味の対象でした、キリンは__複数名詞__の中で一番背が買いですが、科学者たちはそのような長い__体の一部__をどうやって獲得したのか説明できません。キリンの身長は___数値__ __単位__ 近くあり、その高さのほとんどは足と__体の一部__によるものです。 3 4type(txt): <class 'str'> 5type(mls): <class 'str'> 6__複数名詞__を入力: あういえお 7type(answer): <class 'str'> 8__複数名詞__を入力: a 9type(answer): <class 'str'> 10__体の一部__を入力: i 11type(answer): <class 'str'> 12___数値__を入力: u 13type(answer): <class 'str'> 14__単位__を入力: e 15type(answer): <class 'str'> 16__体の一部__を入力: o 17type(answer): <class 'str'> 18 19 20Traceback (most recent call last): 21 File "17-p213.py", line 29, in <module> 22 mad_libs(txt) 23 File "17-p213.py", line 23, in mad_libs 24 print(mls) 25UnicodeEncodeError: 'utf-8' codec can't encode characters in position 8-22: surrogates not allowed

python3

1#!/usr/bin/env python3.6 2# encoding: utf-8 3 4import re 5import io, sys 6sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") 7 8txt = """キリンは大昔から__複数名詞__の興味の対象でした、キリンは__複数名詞__の中で一番背が買いですが、科学者たちはそのような長い__体の一部__をどうやって獲得したのか説明できません。キリンの身長は___数値__ __単位__ 近くあり、その高さのほ>とんどは足と__体の一部__によるものです。 9""" 10 11def mad_libs(mls): 12 hints = re.findall("__.*?__", mls) 13 print("type(mls): ", type(mls)) 14 if hints is not None: 15 for hint in hints: 16 question = "{}を入力: ".format(hint) 17 answer = input(question) 18 print("type(answer): ", type(answer)) 19 # 1つだけ置換 20 mls = mls.replace(hint, answer, 1) 21 print("\n") 22 mls = mls.replace("\n", "") 23 print(mls) 24 else: 25 print("引数: mls が無効です") 26 27print(txt) 28print("type(txt): ", type(txt)) 29mad_libs(txt)

※追記:
export LC_ALL=en_US.UTF-8
をしたら日本語をinput()に渡したら動作するようになりましたが、
exportしなくてもいいように、
import io, sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
を追加したのですが、なぜこのような違いが出るのでしょうか。

bash

1echo $SHELL 2/usr/bin/fish 3 4fish --version 5fish, version 2.7.1 6 7echo $locale 8 9echo $LC_ALL 10 11export LC_ALL=en_US.UTF-8 12echo $locale 13 14echo $LC_ALL 15en_US.UTF-8 16

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2018/11/11 10:05 編集

Windows環境にて再現しません。単純な"あいう"などを入力しても surrogates not allowedになりますか?あるいは別のエラーにならないでしょうか?可能であればエラーのTraceback全文を提示ください。
guest

回答1

0

ベストアンサー

export LC_ALL=en_US.UTF-8でいけるようになるなら、何もしないとロケールの設定が日本語非対応とか、UTF-8と噛み合わないとか、それだけの話です。

環境のロケールを変えて使えば良いような気もしますが、そうしたくない場合は。

python

1sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding="utf-8")

input()使うのならstdinも書き換えましょう。
(質問文にエラー箇所のわかるtracebackが出てないので、たぶんこれじゃないかなぁ、というのを書いているだけで、外しているかもしれません)

投稿2018/11/11 10:39

編集2018/11/11 10:40
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teityura

2018/11/14 03:32

sys.stdinの方も追加してみると解決しました。 回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問