2

2 つの文字列をisで比較しようとしています。1 つの文字列は関数によって返され、もう 1 つの文字列は比較で宣言されているだけです。オブジェクト ID のテストですが、このページによると、Python のメモリ最適化により、2 つの同一の文字列でも機能します。ただし、次の場合は機能しません。

def uSplit(ustring):
        #return user minus host
        return ustring.split('!',1)[0]

user = uSplit('theuser!host')
print type(user)
print user
if user is 'theuser':
    print 'ok'
else:
    print 'failed'

user = 'theuser'

if user is 'theuser':
    print 'ok'

出力:

「str」と入力します
ユーザー
失敗した
わかった

これの理由は、関数によって返される文字列が文字列リテラルとは異なる「タイプ」の文字列であるためだと思います。文字列リテラルを返す関数を取得する方法はありますか? ==を使用できることはわかっていますが、ただ興味があります。

4

3 に答える 3

4

あなたが引用したそのページには、「2つの文字列リテラルが等しい場合、それらは同じメモリ位置に置かれています」と書かれています(私のものを強調してください)。Python はリテラル文字列をインターンしますが、任意の関数から返される文字列は別のオブジェクトです。演算子はisポインター比較と見なすことができるため、2 つの異なるオブジェクトは (同じ文字が含まれていても、つまり等しい場合でも) 同一とは見なされません。

于 2009-08-01T09:50:39.273 に答える
3

あなたが引用したサイトには、次のように書かれています。

2 つの文字列リテラルが等しい場合、それらは同じメモリ位置に配置されています。

しかし

uSplit('theuser!host')

は文字列リテラルではありません。リテラルに対する操作の結果です'theuser!host'

とにかく、通常、 を使用して文字列の等価性をチェックするべきではありませんis。これは、どのような場合でも、このメモリの最適化は、依存すべきではない実装の詳細にすぎないためです。


また、isのようなものに使用する必要がありますis None。これを使用して、設計したクラスの 2 つのオブジェクトが同じインスタンスであるかどうかを確認します。これらの組み込みクラスの作成規則は複雑であるため、文字列や数値に簡単に使用することはできません。一部の文字列はインターンされています。同様に、一部の数は抑留されています。

于 2009-08-01T09:51:16.540 に答える
0

あなたが遭遇したのは、Python が常にすべての文字列をインターンするとは限らないという事実です。詳細はこちら:

http://mail.python.org/pipermail/tutor/2009-July/070157.html

于 2009-08-01T09:52:14.917 に答える