Seltsames Verhalten beim Definieren eines Wertes für True in Python

8

Das ist kein praktisches Problem - ich bin nur neugierig auf ein merkwürdiges Verhalten, das ich beobachtet habe und frage mich, ob ich den "ist" -Operator richtig verstehe.

Hier ist eine vorhersehbare Python-Interpreter-Ausgabe:

%Vor%

Definieren wir nun eine Variable namens True:

%Vor%

Der Interpreter gibt immer noch "True" für boolesche Operationen zurück, aber die Ergebnisse boolescher Operationen werden weder als 'abc' noch als wahr betrachtet.

%Vor%

Kann jemand dieses seltsame Verhalten erklären?

    
Ben Morris 28.10.2013, 15:54
quelle

3 Antworten

2

Um ein bisschen mehr zu Ihrer eigenen Antwort hinzuzufügen (sollte ein Kommentar sein, aber lang und muss formatiert werden):

%Vor%

Der Wert von id ist (im Wesentlichen) die interne Identität oder, wenn Sie so wollen, "wahrer Name" eines Objekts in Python. (Es ist buchstäblich ein C-Zeiger, der in eine Ganzzahl umgewandelt wird.) Der is -Test vergleicht die Objektidentität.

%Vor%

Dies zeigt, dass das boolesche Ergebnis eines Vergleichs das "alte" True ist, das noch als __builtin__.True verfügbar ist.

Sie haben den Namen __main__.True erneut gebunden (Ihr aktuelles Modul an der Eingabeaufforderung des Interpreters >>> ist __main__ ):

%Vor%

und:

%Vor%

Dieselbe Sache passiert sehr oft in Python-Programmen für Anfänger, wenn sie Funktionen schreiben wie:

%Vor%

list ist eine eingebaute Funktion, aber innerhalb der Funktion foo wurde der Name wieder an das Argument gebunden. Dann irgendwo im ... Teil bekommen sie eine Überraschung:

%Vor%

Sie erwarten, dass dies __builtin__.list aufruft, aber es versucht stattdessen, ihre lokale Variable als Funktion aufzurufen.

(Es ist möglich, aber nicht generell guter Stil, zu import __builtin__ und rufen Sie die Dinge stattdessen durch diese Namen. Es ist auch möglich, die __builtin__ Namen neu zu binden, aber das ist eine noch schlimmere Idee. :-))

    
torek 28.10.2013, 16:07
quelle
6

Wie so oft hier, denke ich, dass ich die Antwort herausgefunden habe, während ich die Frage eintippte.

Es gibt zwei "Wahre" s: Eins ist ein boolescher Wert, und das andere ist die Variable namens True; Anfangs sind sie einander gleich. Aus diesem Grund können Boolesche Operationen wie (1 == 1) auch dann True zurückgeben, wenn die Variable True geändert wurde - sie geben den booleschen Wert True zurück. Sie sind jedoch nicht gleich dem neuen Wert der "True" -Variable, die eine Zeichenfolge ist.

    
Ben Morris 28.10.2013 15:54
quelle
5

Das geschieht durch Namespace und die interaktive Konsole, die es versteckt.

Zunächst haben Sie normal True , was ein Teil von __builtin__ module ist.

Wenn du True neu definierst, definierst du es in einem aktuellen Modul, was in diesem Fall nur ein Standard __main__ ist.

Sie haben also tatsächlich zwei verschiedene Objekte. __builtin__.True und __main__.True .

%Vor%     
vartec 28.10.2013 16:06
quelle