9

print obj呼び出すと呼び出しobj.__str__()が発生し、文字列が返されてコンソールに出力されることを理解しました。今、私はUnicodeで、ASCII以外の文字を印刷できないという問題に直面しています。私は典型的な「範囲外のASCII」のものを手に入れました。

実験中、以下が機能しました:

print obj.__str__()
print obj.__repr__()

両方の関数がまったく同じように動作します(__str__()を返すだけself.__repr__()です)。うまくいかなかったもの:

print obj

この問題は、ASCII範囲外の文字を使用した場合にのみ発生しました。最終的な解決策は、次のようにすることでした__str__()

return self.__repr__().encode(sys.stdout.encoding)

今ではすべての部分で機能します。私の質問は今です:違いはどこにありますか?なぜ今それが機能するのですか?何も機能しなかった場合、なぜこれが機能するのかがわかります。しかし、なぜ下部ではなく上部のみが機能するのでしょうか。

OSはWindows7x64で、デフォルトのWindowsコマンドプロンプトがあります。また、エンコーディングはであると報告されていますcp850。これは、Pythonを理解するためのより一般的な質問です。私の問題はすでに解決されていますが、100%満足しているわけではありません。これは主に、今すぐ呼び出すstr(obj)と、希望どおりにエンコードされていない文字列が生成されるためです。

# -*- coding: utf-8 -*- 
class Sample(object):

    def __init__(self):
        self.name = u"üé"

    def __repr__(self):
        return self.name

    def __str__(self):
        return self.name

obj = Sample()
print obj.__str__(), obj.__repr__(), obj

最後を削除しobj、それが動作します。それを維持し、それはでクラッシュします

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
4

2 に答える 2

4

私の推測では、printは、印刷objすることを意図したオブジェクトに対して次のようなことを行います。

  1. objがであるかどうかを確認しunicodeます。もしそうなら、それをにエンコードしてsys.stdout.encoding印刷します。
  2. objがであるかどうかを確認しstrます。もしそうなら、それを直接印刷します。
  3. objそれ以外の場合は、それを呼び出しstr(obj)て印刷します。

print obj.__str__()ステップ1.があなたのケースで機能する理由です。

さて、何をstr(obj)しますか:

  1. を呼び出しobj.__str__()ます。
  2. 結果が、の場合は、strそれを返します
  3. 結果がである場合、unicodeそれをにエンコードして"ascii"返します
  4. そうでなければ、ほとんど役に立たない何か。

直接呼び出すobj.__str__()と、手順2〜3がスキップされます。そのため、エンコードに失敗することはありません。

問題はどのように機能するかによって引き起こされるprintのではなく、どのように機能するかによって引き起こされますstr()str()を無視しsys.stdout.encodingます。結果の文字列をどのように処理するかがわからないため、使用するデフォルトのエンコーディングは任意と見なすことができます。ascii良いか悪いかの選択です。

このバグを防ぐには、ドキュメントに記載されているように、strからを返すようにしてください。__str__()Python2.xに使用できるパターンは次のとおりです。

class Foo():
    def __unicode__(self):
        return u'whatever'
    def __str__(self):
        return unicode(self).encode(sys.stdout.encoding)

str()(コンソールへの印刷以外の表現は必要ないと確信している場合。)

于 2012-07-03T22:40:07.920 に答える
1

まず、オンラインドキュメントを見て__str____repr__目的が異なり、異なる出力を作成する必要がある場合。したがって、__repr__からの呼び出し__str__は最善の解決策ではありません。

次に、printを呼び出し__str__、非ASCII文字を受信することを期待しませんprint。これは、非ASCII文字を変換する方法を推測できないためです。

最後に、Python 2.xの最近のバージョンで__unicode__は、オブジェクトの文字列表現を作成するための推奨される方法です。Pythonstrとunicodeには興味深い説明があります

したがって、質問に実際に答えるために、次のようなことを行うことができます。

class Sample(object):

    def __init__(self):
        self.name = u"\xfc\xe9"

    # No need to implement __repr__. Let Python create the object repr for you

    def __str__(self):
        return unicode(self).encode('utf-8')

    def __unicode__(self):
        return self.name
于 2012-07-03T21:54:23.217 に答える