2009-08-01 12 views
1

Ich versuche, zwei Strings mit ist zu vergleichen. Eine Zeichenfolge wird von einer Funktion zurückgegeben und die andere wird nur im Vergleich deklariert. ist Tests für Objektidentität, aber nach this page funktioniert es auch mit zwei identischen Zeichenfolgen wegen Python Speicheroptimierung. Aber, folgendes nicht:Vergleichen von zwei Strings mit 'ist' - nicht wie erwartet

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'

Der Ausgang:

type 'str' 
theuser 
failed 
ok

Ich vermute, der Grund für diese eine Zeichenfolge durch eine Funktion zurückgegeben wird, ist eine andere „Art“ von String als ein String-Literal. Gibt es trotzdem eine Funktion, um ein String-Literal zurückzugeben? Ich weiß, ich könnte == verwenden, aber ich bin nur neugierig.

+0

das 'is' Schlüsselwort ist Identität zu überprüfen, nicht Gleichheit, so ist es das falsche Werkzeug für den Job sowieso. – nosklo

Antwort

2

Die Website, die Sie dieses Zitat sagt:

Wenn zwei Zeichenketten gleich sind, haben sie denselben Speicherplatz gesetzt worden.

Aber

uSplit('theuser!host') 

ist kein Stringliteral - es ist das Ergebnis einer Operation auf der wörtlichen 'theuser!host' ist.

Wie auch immer, normalerweise sollten Sie nicht auf Zeichengleichheit mit is überprüfen, da diese Speicheroptimierung in jedem Fall nur ein Implementierungsdetail ist, auf das Sie sich nicht verlassen sollten.


Außerdem sollten Sie is wie is None für Dinge verwenden. Verwenden Sie es zum Überprüfen, ob zwei Objekte - von Ihnen entworfene Klassen - dieselbe Instanz sind. Sie können es nicht einfach für Strings oder Zahlen verwenden, da die Regeln für die Erstellung dieser integrierten Klassen komplex sind. Einige Zeichenfolgen sind interniert. Einige Zahlen sind ähnlich interniert.

+0

Die Regeln für das Praktikum sind in der Tat seltsam. Wenn uSplit eine Zeichenfolge mit 2 oder weniger Zeichen zurückgegeben hat, funktioniert der Vergleich "is". Ich denke, es ist am sichersten bei der Verwendung von == zu bleiben. –

+2

Es ist kein "Sicherster". Es ist eine Frage der Definition. Zeichenfolgen sind nicht als immer intern definiert.Einige sind, aber es gibt keine explizite Garantie, so dass Sie einfach nicht 'is' mit Strings verwenden können. Es ist keine Sicherheit, sondern eine Frage der Definition. –

+1

Genau. "ist" hat seinen Zweck, "==" hat seinen Zweck. Verschiedene Zwecke. – balpha

3

Die von Ihnen zitierte Seite sagt "Wenn zwei Zeichenfolgen Literale gleich sind, wurden sie an denselben Speicherort gesetzt" (Betonung meiner). Python Internes literale Strings, aber Strings, die von einer beliebigen Funktion zurückgegeben werden, sind separate Objekte. Der Operator is kann als ein Zeigervergleich betrachtet werden, so dass zwei verschiedene Objekte nicht als identisch verglichen werden (selbst wenn sie dieselben Zeichen enthalten, dh sie sind gleich).

+0

In dem größeren Schema der Dinge, ist es selten, dass jede Sprache starke Garantien über den Speicher auf einem verwalteten Speichersystem gibt (Garbage Collection oder Referenzzählung mit Zykluserkennung). Selbst wenn sie es tun, ist es im Allgemeinen nicht gut, sich darauf zu verlassen, weil die Garantie in zukünftigen Versionen verschwinden könnte. – Imagist

Verwandte Themen