Yanıtlar:
İfade
if A:
arayacaktır A.__nonzero__()(bkz. Özel yöntem adları belgeleri) ve bu işlevin dönüş değerini kullanır. İşte özet:
object.__nonzero__(self)Gerçeğe uygun değer testi ve yerleşik işlemi uygulamaya çağırdı
bool(); dönmelidirFalseveyaTrueveya bunların tamsayı eşdeğerleri0ya1. Bu yöntem tanımlanmadığında, tanımlanmışsa__len__()çağrılır ve sonucu sıfırdan farklıysa nesne true olarak kabul edilir. Bir sınıf ne__len__()de ne de tanımlarsa__nonzero__(), tüm örnekleri doğru kabul edilir.
Diğer yandan,
if A is not None:
aynı olup olmadığını görmek için yalnızca başvuruyu Aile karşılaştırır None.
if object(): passdöngü başına ~ 0.130 usec iken if object() is not None: pass~ 0.135 usec'dir. Her neyse, bu ikisi arasında seçim yapmak için performansı kullanmamalısınız, aksine eşdeğer olmadıkları için nasıl çalıştıkları arasındaki farklılıklara bakmalısınız .
if A is not Nonedaha yavaş görünüyor çünkü bu bir karşılaştırma ve yerleşik singleton Noneile karşılaştırmak için bir ara adım olarak yüklenmesi gerekiyor A(bir göz atın dis.dis()). Eğer yanılıyorsam beni düzeltin ama kimliğinizi if A:değil, doğruluk değerini gerçekten test etmek istediğinizde daha verimli görünüyor None.
python -m timeit -s"a=0" "if a: pass" "else: pass"daha hızlı python -m timeit -s"a=0" "if a is None: pass" "else: pass"ama python -m timeit -s"a=1" "if a: pass" "else: pass"daha yavaş. Platforma bağlı olabilir, aynı sonuçları alıp almadığınızı görün
is Nonetest gerçekten benim için en yavaştı . Pypy'de hepsi aynı şekilde ölçüldü :)
PEP8'de yazıldığı gibi :
Hiçbiri gibi singletonlarla karşılaştırmalar daima 'is' veya 'not' ile yapılmamalıdır, asla eşitlik operatörleri kullanılmamalıdır .
Ayrıca, gerçekten "x Hiçbiri değilse" demek istediğinizde "if x" yazmayı unutmayın - örneğin, varsayılan değer olarak None değerine sahip bir değişkenin veya bağımsız değişkenin başka bir değere ayarlanıp ayarlanmadığını test ederken. Diğer değer, bir boole bağlamında yanlış olabilecek bir türe (kap gibi) sahip olabilir!
Nonedeğil, sadece bir doğruluk değeri kontrolüyle ilgilenir . Bu durumda, if A:daha verimli görünüyor (a dis.dis(), yerleşik olanı yüklemek ve diğer durumda sadece bir varken Nonekarşılaştırmak için ekstra adımlar if A is not None:var jump_if).
if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None
yani aynı değil
if x is not None # which works only on None
Uygun sonuç yoksa birçok işlev Yok değerini döndürür. Örneğin .first(), sonuçta satır yoksa bir SQLAlchemy sorgusunun yöntemi Yok değerini döndürür. 0 döndürebilecek bir değer seçtiğinizi ve bunun gerçekten 0 olup olmadığını veya sorgunun hiç sonucu olup olmadığını bilmeniz gerektiğini varsayalım.
Sık kullanılan bir deyim, bir işleve veya yöntemin isteğe bağlı bağımsız değişkenine varsayılan Yok değerini vermek ve daha sonra bu değerin belirtilip belirtilmediğini görmek için Yok değerini sınamaktır. Örneğin:
def spam(eggs=None):
if eggs is None:
eggs = retrievefromconfigfile()
bunu şununla karşılaştır:
def spam(eggs=None):
if not eggs:
eggs = retrievefromconfigfile()
İkincisinde, spam(0)ya ararsanız ne olur spam([])? Bu işlev (yanlış) için bir değer eggsaktarmadığınızı saptar ve sizin için varsayılan bir değer hesaplar. Muhtemelen istediğin bu değil.
Veya "belirli bir hesap için işlem listesini döndür" gibi bir yöntem düşünün. Hesap yoksa, Yok'u döndürebilir. Bu, boş bir liste döndürmekten farklıdır (bu, "bu hesap var, ancak işlem kaydetmemiş anlamına gelir).
Son olarak, veritabanı şeyler geri. NULL ve boş bir dize arasında büyük bir fark var. Boş bir dize genellikle "burada bir değer vardır ve bu değer hiçbir şey değildir" der. NULL, "bu değer girilmedi" diyor.
Her iki durumda da kullanmak istersiniz if A is None. Belirli bir değeri kontrol ediyorsunuz - Yok - sadece "False'a yapılan herhangi bir değer" değil.
Çok farklı şeyler yapıyorlar .
Aşağıdaki kontroller A değerlerine dışında bir şey varsa False, [], None, ''ve 0. A'nın değerini kontrol eder .
if A:
Aşağıda A'nın Yok'tan farklı bir nesne olup olmadığı kontrol edilmektedir. A ve Hiçbirinin referansını (bellek adresi) kontrol eder ve karşılaştırır .
if A is not None:
GÜNCELLEME: Daha fazla açıklama
Çoğu zaman ikisi aynı şeyi yapıyor gibi görünüyor, bu yüzden birçok insan bunları birbirinin yerine kullanıyor - bu gerçekten kötü bir fikir. İkisinin de aynı sonuçları vermesinin nedeni, tercüman / derleyicinin stajyerlik veya başka bir şey gibi optimizasyonları nedeniyle saf tesadüflerdir .
Bu optimizasyonlar göz önünde bulundurulduğunda, aynı değere sahip tamsayılar ve dizeler aynı bellek alanını kullanır. Muhtemelen iki ayrı dizginin neden aynıymış gibi hareket ettiğini açıklar.
> a = 'test'
> b = 'test'
> a is b
True
> a == b
True
Diğer şeyler de aynı şekilde davranmıyor ..
> a = []
> b = []
> a is b
False
> a == b
True
İki listenin kendi hafızası açıkça var. Şaşırtıcı bir şekilde tuples dizeleri gibi davranır.
> a = ()
> b = ()
> a is b
True
> a == b
True
Muhtemelen bunun nedeni tuplelerin değişmeyeceği garantilidir, bu nedenle aynı belleği tekrar kullanmak mantıklıdır.
Sonuçta tesadüflere güvenemezsiniz . Ördek gibi quacks olması ördek olduğu anlamına gelmez. Kullanım isve ==gerçekten kontrol etmek istediğinize bağlı. Bu tür şeyleri ayıklamak zor olabilir is, çünkü genellikle sadece gözden geçirdiğimiz düzyazı gibi okur.
Nonesingleton, bir uygulama detayı değildir (int veya string interning'in aksine). Ne demek istediğini takip ettiğimden emin değilim.
Nonefarklı davranması değil . Demek istediğim şu ve farklı şeyleri kontrol ediyorlar ; ilk önce bir bellek adresini, ikincisi bellek adreslerinin içeriğini kontrol eder. intstris==
if A: A 0, Yanlış, boş dize, boş liste veya Yok ise yanlış sonucunu verir, bu da istenmeyen sonuçlara yol açabilir.
Gördüğüm çoğu rehber kullanmanız gerektiğini gösteriyor
Eğer bir:
daha spesifik olmak için bir nedeniniz yoksa.
Bazı ufak farklılıklar var. Hiçbiri dışında False döndüren değerler vardır, örneğin boş listeler veya 0, bu yüzden gerçekten ne için test ettiğinizi düşünün.
Yok, Python'da genellikle başlatılmamış bir değişken belirten özel bir değerdir . A'nın kullandığınız bu değere sahip olup olmadığını test etmek için:
if A is not None
Falsey değerleri, Python'daki özel bir nesne sınıfıdır (örneğin false, []). A'nın falsey olup olmadığını test etmek için:
if not A
Böylece, iki ifade aynı değildir. Onlara eşanlamlı olarak davranmasanız iyi olur.
PS None aynı zamanda falseydir, bu nedenle ilk ifade ikincisini ifade eder. Ancak ikincisi Yok'un yanı sıra diğer falsey değerlerini de kapsar. Şimdi ... A'da Hiçbiri dışında başka bir falsey değerine sahip olamayacağınızdan eminseniz, ilk ifadeyi ikincisiyle değiştirebilirsiniz.
Bu koşullara bağlıdır.
Bir çeşit koleksiyon if A:olmasını beklediğimde Akullanıyorum ve sadece koleksiyon boş değilse bloğu yürütmek istiyorum. Bu, arayan kişinin boş veya değil, iyi kalpli bir koleksiyonu geçirmesini ve beklediğim şeyi yapmasını sağlar. Ayrıca , bazen çağrı kodu için uygun olan bloğun yürütülmesine izin verir Noneve Falsebastırır.
Otoh, beklediğim eğer Abazı tamamen keyfi bir nesne olmak ancak varsayılan ayarı olabilirdi Noneo zaman ben her zaman kullanmak if A is not Nonekod çağıran kasten boş toplama, boş bir dizge veya bir 0-değerli sayısal tür bir başvuru geçirilen olabilirdi, ya da boolean Falseveya boolean bağlamında yanlış olan bazı sınıf örnekleri.
Öte yandan, Adaha spesifik bir şey olmasını bekliyorsam (örneğin, yöntemlerini çağıracağım bir sınıf örneği), ancak varsayılan olarak ayarlanmış olabilir Noneve varsayılan boolean dönüşümü bir sınıfın özelliği Tüm alt sınıfları zorlamak umursamıyorum, o zaman sadece if A:parmaklarımı fazladan 12 karakter yazmanın korkunç yükünü kurtarmak için kullanacağım .
Adlı bir dosya oluşturdum test.pyve yorumlayıcıda çalıştırdım. Sahnelerin arkasında neler olup bittiğinden emin olmak için ne yapmak istediğinizi değiştirebilirsiniz.
import dis
def func1():
matchesIterator = None
if matchesIterator:
print( "On if." );
def func2():
matchesIterator = None
if matchesIterator is not None:
print( "On if." );
print( "\nFunction 1" );
dis.dis(func1)
print( "\nFunction 2" );
dis.dis(func2)
Bu montajcı farkıdır:

Kaynak:
>>> import importlib
>>> reload( test )
Function 1
6 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
8 6 LOAD_FAST 0 (matchesIterator)
9 POP_JUMP_IF_FALSE 20
10 12 LOAD_CONST 1 ('On if.')
15 PRINT_ITEM
16 PRINT_NEWLINE
17 JUMP_FORWARD 0 (to 20)
>> 20 LOAD_CONST 0 (None)
23 RETURN_VALUE
Function 2
14 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
16 6 LOAD_FAST 0 (matchesIterator)
9 LOAD_CONST 0 (None)
12 COMPARE_OP 9 (is not)
15 POP_JUMP_IF_FALSE 26
18 18 LOAD_CONST 1 ('On if.')
21 PRINT_ITEM
22 PRINT_NEWLINE
23 JUMP_FORWARD 0 (to 26)
>> 26 LOAD_CONST 0 (None)
29 RETURN_VALUE
<module 'test' from 'test.py'>
python> = 2.6,
şöyle yazarsak
if A:
olarak uyarı üretecek,
FutureWarning: Bu yöntemin davranışı gelecekteki sürümlerde değişecektir. Bunun yerine özel 'len (elem)' veya 'elem None değil' testini kullanın.
Böylece kullanabiliriz
if A is not None:
A is not Nonedaha az iş yapıldığı için daha hızlı