2010-01-13 9 views
31

Başka bir soruyu yanıtlamanın bir parçası olarak, ilk bakışta davranışı tuhaf görünen şu kodu yazdım:Neden Doğru/Yanlış'a atama beklediğim gibi çalışmıyor?

print True     # outputs true 
True = False; print True # outputs false 
True = True;  print True # outputs false 
True = not True; print True # outputs true 

Bu garip davranışı herkes açıklayabilir mi? Sanırım Python'un nesne modeliyle bir ilgisi var ama emin değilim.

Bu Cygwin sürümü 2.5.2 sürümüdür.

+18

o eski güzel şaka '#define gerçek FALSE değil mi eylem burada? – Amarghosh

+2

Sürüm 3'te True = False ifadesi bir sintaks hatası ortaya çıkarır, bu yüzden sorunuzun 2 – jab

+2

sürümüyle ilgili garip bir durum olduğunu varsayalım? detaylandırmak için bakım? – ghostdog74

cevap

73

Python bu ikisi (diğerleri arasında) yerleşik nesneye sahiptir. Onlar sadece nesnelerdir; Başlangıçta, henüz herhangi bir isimleri yok, ama biz neye atıfta bulunduğumuzu bilmek için, onlara 0x600D ve 0xBAD diyelim. Program True atıfta zaman

bir Python (2.x) komut dosyası çalıştırmak için başlamadan önce, adı True nesneye 0x600D bağlı alır ve adı False nesneye 0xBAD bağlı olur, yani, bu 0x600D bakar .

0x600D ve 0xBAD genellikle isimlerin True ve False tarafından kullanıldığını bilmek için, onlar basılmış olsun zaman ne çıktı var, yani 0x600D getiriler 'True' ve benzeri bir __str__ yöntemi.

True = False 

artık farklı bir nesne için adı True bağlanır. Bundan sonra, True ve False adlarının her ikisi de False çıktıları çıktığında False çıktıları ile aynı nesneyi ifade eder.

True = True 

gerçekten bir şey yapmaz: Bu isim True ile anılan nesneyi alır ve bu nesneye yeni (ve eski) adını True bağlanır. Bundan önce (önceki adımdan dolayı) True, bundan önce 0xBAD anlamına gelir, bundan sonra hala 0xBAD anlamına gelir. Bu nedenle, baskı hala False çıkışlarıdır. İlk

True = not True 

adı True0xBAD olan bağlı olduğu nesne alır. Bu nesneyi not operatörüne verir. not, 0xBAD'a başvurmak için hangi adı kullandığını (veya bilmediğini) bilmiyor, sadece 0xBAD verildiğinde 0x600D'u döndürmesi gerektiğini biliyor.Bu dönüş değeri, = numaralı atama operatörüne bu nesneye True adını bağlayarak verilir. adı True yana

şimdi bir kez daha print True çıkışları True çağıran nesneye 0x600D ifade eder ve dünya yeniden iyidir.

True = 1==1 
False = 1==0 

Veya bool değerlerden oluşan için tamsayı değişmezleri dönüştürerek:

+16

@paxdiablo: Sen neden bahsediyorsun, "anımsatıcılar"? Bunlar, her iyi Python uygulamasının şu nesneleri tutması gereken hafıza adresleri: -P – balpha

+0

@ user127555 Biliyorum; "atama bir ifade değil" en sevdiğim Python özelliklerinden biridir. Ancak "görevlendirme operatörü" ile ilgili olarak: [Resmi belgeler] (https://docs.python.org/2/reference/simple_stmts.html) bile bu adla başvurur. – balpha

17

2.x'de, True ve False anahtar sözcükler değildir, bu nedenle yerleşikleri bu şekilde gölgelemek mümkündür.

41

yerine bu hayal:

A = True 
B = False 

print A   # true 
A = B; print A # false 
A = A; print A # false, because A is still false from before 
A = not A; print A # true, because A was false, so not A is true 

aynı şeyi oluyor, ama sen True ve False yeniden tanımlayabilirsiniz beklemiyoruz çünkü sürümünde bu kafa karıştırıcı. False = Doğru sadece "Doğru" anlamına başka bir "değişken" adıdır atama (benim sürümde) olmadığına göre

>>> import keyword 
>>> keyword.iskeyword('True') 
False 

:

11

Sen ister Doğru/Yanlış kontrol edebilirsiniz bir anahtar kelimedir.

+1

Belki de 'keyword.iskeyword ('True')' anahtar sözcüğünü kullanmanız gereken bir nottur. Bunun yerine bir örnek olarak, çoğu gerçek anahtar kelime orada kullanıldığında bir SyntaxError vereceğinden. –

+0

@Ig, sure.thanks – ghostdog74

+2

Not: Bu, python 3'te sabittir, True bir [anahtar kelime] 'dir (https://docs.python.org/3/reference/lexical_analysis.html#keywords). –

0

Kolayca basit Boole karşılaştırmalar kullanarak orijinal değerleri geri verebilir

True = bool(1) # actually every number except 0 works 
False = bool(0)