7

これを機能させるにはいくつかの問題がありました:

# Shortened for brevity
def _coerce_truth(word):
    TRUE_VALUES = ('true','1','yes')
    FALSE_VALUES = ('false','0','no')

    _word = word.lower().strip()
    print "t" in _word
    if _word in TRUE_VALUES:
        return True
    elif _word in FALSE_VALUES:
        return False

私は発見した:

In [20]: "foo" is "Foo".lower()
Out[20]: False

In [21]: "foo" is "foo".lower()
Out[21]: False

In [22]: "foo" is "foo"
Out[22]: True

In [23]: "foo" is "foo".lower()
Out[23]: False

どうしてこれなの?アイデンティティは平等とは異なることは理解していますが、アイデンティティはいつ形成されますか? ステートメント 22 はFalse、文字列の静的な性質により、id == eq でなければなりません。この場合、私はステートメント 23 に混乱しています。

事前に説明して感謝します。

4

3 に答える 3

7

Q.「アイデンティティーはいつ形成されますか?」

A. オブジェクトが作成されたとき。

あなたが見ているのは、実際にはCpythonの実装の詳細です.Cpythonは小さな文字列をキャッシュし、効率のためにそれらを再利用します. 興味深い他のケースは次のとおりです。

"foo" is "foo".strip()  # True
"foo" is "foo"[:]       # True

"foo"最終的に、文字列リテラルがキャッシュされていることがわかります。と入力するたび"foo"に、メモリ内の同じオブジェクトを参照しています。ただし、文字列メソッドの中には常に新しいオブジェクトを作成することを選択するもの ( など.lower()) もあれば、メソッドが変更を加えていない場合に入力文字列をスマートに再利用するもの ( など.strip()) もあります。


これの利点の 1 つは、ポインター比較が偽の場合は、ポインター比較 (非常に高速) に続いて文字ごとの比較を行うことで、文字列の等価性を実装できることです。ポインター比較が True の場合、文字ごとの比較を回避できます。

于 2013-09-19T20:45:01.050 に答える
3

isとの関係はin:

メソッド (演算子の背後にある) は、__contains__一致を探している間、最初に ID をチェックし、それが一致しない場合は等しいかどうかをチェックします。これにより、オブジェクト自体と比較して等しくない場合でも、適切な結果が得られます。intuplelist

>>> x = float("NaN")
>>> t = (1, 2, x)
>>> x in (t)
True
>>> any(x == e for e in t) # this might be suprising
False
于 2013-09-19T21:02:42.603 に答える
0

「foo」の文字列値を持つオブジェクトを作成する方法がたくさんあるとします。

def f(s): return s.lower()

li=['foo',                     # 0
    'foo'.lower(),             # 1
    'foo'.strip(),             # 2
    'foo',                     # 3
    'f'+'o'*2,                 # 4
    '{}'.format('foo'),        # 5
    'f'+'o'+'o',               # 6
    intern('foo'.lower()),     # 7
    'foo'.upper().lower(),     # 8
    f('foo'),                  # 9
    'FOO'.lower(),             # 10
    'foo',                     # 11
    format('foo'),             # 12
    '%s'%'foo',                # 13
    '%s%s'%('fo','o'),         # 14
    'f'   'oo'                 # 15
]

isTrueオブジェクトが同じidを持つ場合にのみ解決されます。これをテストして、実行時に同じ不変文字列にインターンされた文字列オブジェクトを確認できます。

def cat(l):
    d={}
    for i,e in enumerate(l):
        k=id(e)
        d.setdefault(k,[]).append(i)

    return '\n'.join(str((k,d[k])) for k in sorted(d)) 

版画:

(4299781024, [0, 2, 3, 6, 7, 11, 12, 13, 15])
(4299781184, [5])
(4299781784, [1])
(4299781864, [4])
(4299781904, [9])
(4299782944, [8])
(4299783064, [10])
(4299783144, [14])

ほとんどが同じ文字列オブジェクトに解決 (またはインターン) されていることがわかりますが、そうでないものもあります。これは実装に依存します。

関数internを使用して、それらをすべて同じ文字列オブジェクトにすることができます。

print cat([intern(s) for s in li]) 

版画:

(4299781024, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
于 2013-09-19T20:53:15.187 に答える