Python3での、MIME文書と文字列の操作に関する質問です。


下記のエントリで書いたのですが、
https://www.statsbeginner.net/entry/2018/09/29/230716

smtplibのHeader()関数で生成したインスタンスの最後に.encode()というメソッドを引数なしで付け加えており、それで正常に動いているのですが、この引数なしのメソッドはどういう役割を果たしているのでしょうか?

同じような記法を、文字列のインスタンスに対しても行っている例を見たことがあります。これを付けないと何が不都合なのでしょうか?

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2018/10/02 18:41:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4973ベストアンサー獲得回数2154

ポイント100pt

smtplibのHeader()関数で生成したインスタンスの最後に.encode()というメソッドを引数なしで付け加えており、それで正常に動いているのですが、この引数なしのメソッドはどういう役割を果たしているのでしょうか?

これは email.header.Header クラスの encode() メソッドです。
https://docs.python.jp/3/library/email.header.html#email.header.Header.encode

メッセージヘッダを RFC に沿ったやり方でエンコードします。おそらく長い行は折り返され、非 ASCII 部分は base64 または quoted-printable エンコーディングで包含されるでしょう。


RFC-2047 にそった、以下の形式の文字列を取得できます。

encoded-word = "=?" charset "?" encoding "?" encoded-text "?="

https://tools.ietf.org/html/rfc2047.html

同じような記法を、文字列のインスタンスに対しても行っている例を見たことがあります。

こちらは、string クラスの encode() メソッドです。
https://docs.python.jp/3/library/stdtypes.html#str.encode

文字列のエンコードされたバージョンをバイト列オブジェクトとして返します。

原文の直訳になっちゃってますが、文字コードの変換を行います。
引数なしで呼ばれているときは、デフォルトの "utf-8" への変換を行います。

「記法」というか、メソッドの呼び出しなので、メソッド名が同じでも、そのクラスがどんなクラスかによって処理内容は変わります。

これを付けないと何が不都合なのでしょうか?

「これを付けないと」は、メールヘッダーの方の話だと思いますが、%-書式化で %s で受け取ってますから、string を渡してあげなくてはいけません。

mail_address = メアド
sender_name = Header('差出人名'.encode('iso-2022-jp'),'iso-2022-jp').encode()
sender = '%s <%s>' % (sender_name, mail_address)

email.header.Header クラスには、__str__() メソッドもあるので、str() 関数で変換するのでも構いません。

mail_address = メアド
sender_name = str(Header('差出人名'.encode('iso-2022-jp'),'iso-2022-jp'))
sender = '%s <%s>' % (sender_name, mail_address)

https://docs.python.jp/3/library/email.header.html#email.header.Header.__str__
https://docs.python.jp/3/library/stdtypes.html#str

他1件のコメントを見る
id:a-kuma3

あといま気づきましたが、Header()の1つめの引数に、'差出人名'.encode('iso-2022-jp')としてエンコードしたバイト文字列?を与えていましたが、ここは単にstr型を与えてもいけるようでした。

コンストラクタ、及び、append() メソッドのところに以下のようにあります。

https://docs.python.jp/3/library/email.header.html#email.header.Header

s は bytes または str のインスタンスにできます。このセマンティクスについては append() の項を参照してください。


https://docs.python.jp/3/library/email.header.html#email.header.Header.append

s は bytes または str のインスタンスです。 bytes のインスタンスの場合、 charset はその文字列のエンコーディングであり、この文字セットでデコードできないときは UnicodeError が発生します。

str.encode() メソッドの戻り値は bytes なので、上記の動作をしています。
「単にstr型を与えても」は、こちらの動作になります。

s が str のインスタンスの場合、 charset はその文字列の文字セットを決定するためのヒントとして使われます。

2018/09/30 16:39:21
id:midnightseminar

ありがとう御座います。一応挙動に違いがあったんですね。

2018/10/02 18:40:57

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません