Python'daki null nesneye nasıl başvurabilirim?
Python'daki null nesneye nasıl başvurabilirim?
Yanıtlar:
Python'da 'null' nesnesi singleton'dur None.
Bir şeyi "Noneness" için kontrol etmenin en iyi yolu kimlik operatörünü kullanmaktır is:
if foo is None:
...
None, Python boş mu?nullPython'da yok , bunun yerine var None. Daha önce de belirtildiği gibi, bir şeyin Nonedeğer olarak verildiğini test etmenin en doğru yolu is, iki değişkenin aynı nesneye atıfta bulunduğunu test eden kimlik operatörünü kullanmaktır .
>>> foo is None
True
>>> foo = 'bar'
>>> foo is None
False
NoneNonesınıfın tek örneğidir ve bu sınıfı NoneTypesomutlaştırmak için yapılan herhangi bir girişim aynı nesneyi döndürür ve bu da Nonetekil bir ton oluşturur. Python'a yeni gelenler genellikle NoneTypebunun ne olduğunu belirten ve merak eden hata mesajlarını görürler . Benim kişisel görüşüm, bu mesajların sadece Noneisminden bahsedebileceği için, kısa bir süre sonra göreceğimiz gibi, Nonebelirsizliğe çok az yer bırakıyor. Dolayısıyla , bunu yapamayan veya yapamayan bir TypeErrormesaj görürseniz NoneType, sadece Nonebunun yapamayacağı şekilde kullanılan mesaj olduğunu bilin .
Ayrıca, Noneyerleşik bir sabittir, Python'u başlatır başlatmaz modül, sınıf veya işlevde her yerden kullanılabilir. NoneTypeaksine, Nonesınıfını sorgulayarak ilk önce bir referans almanız gerekir .
>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType
None'In benzersizliğini Python'un kimlik fonksiyonu ile kontrol edebilirsiniz id(). Bir nesneye atanan benzersiz sayıyı döndürür, her nesnenin bir tane vardır. İki değişkenin kimliği aynı ise, aslında aynı nesneye işaret ederler.
>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000
None üzerine yazılamazPython'un çok daha eski bir versiyonunda (2.4'ten önce) yeniden atamak mümkün None, ancak artık değil. Sınıf özniteliği olarak veya bir işlevin sınırlarında bile.
# In Python 2.7
>>> class SomeClass(object):
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: cannot assign to None
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to None
# In Python 3.5
>>> class SomeClass:
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: invalid syntax
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to keyword
Bu nedenle, tüm Nonereferansların aynı olduğunu varsaymak güvenlidir . "Özel" yok None.
Nonekullanmayı test etmek içinisKod yazarken Noneness'i böyle test etmek isteyebilirsiniz :
if value==None:
pass
Ya da böyle bir yanlışlığı test etmek için
if not value:
pass
Sonuçları ve neden açık olmanın genellikle iyi bir fikir olduğunu anlamalısınız.
Noneneden bunu yapıyorsun
value is None
ziyade
value==None
Birincisi şuna eşittir:
id(value)==id(None)
İfade value==Noneaslında böyle uygulanırken
value.__eq__(None)
değer gerçekten ise Noneo zaman ne beklediğiniz alırsınız.
>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True
Çoğu durumda sonuç aynı olacaktır, ancak __eq__()yöntem herhangi bir doğruluk garantisini geçersiz kılan bir kapı açar, çünkü özel davranış sağlamak için bir sınıfta geçersiz kılınabilir.
Bu sınıfı düşünün.
>>> class Empty(object):
... def __eq__(self, other):
... return not other
Yani deniyorsun Noneve işe yarıyor
>>> empty = Empty()
>>> empty==None
True
Ama sonra boş dizede de çalışır
>>> empty==''
True
Ve henüz
>>> ''==None
False
>>> empty is None
False
NoneBoole olarak kullanmaAşağıdaki iki test
if value:
# do something
if not value:
# do something
aslında şu şekilde değerlendiriliyor
if bool(value):
# do something
if not bool(value):
# do something
None"falsey" dir, yani bir boole gönderilirse geri döner Falseve notoperatör uygulandığında geri döner True. Ancak bunun benzersiz bir özellik olmadığını unutmayın None. FalseKendisine ek olarak , özellik boş listeler, tuples, kümeler, dikteler, dizeler yanı sıra 0 ve __bool__()geri dönmek için sihirli yöntemi uygulayan sınıflardan tüm nesneler tarafından paylaşılır False.
>>> bool(None)
False
>>> not None
True
>>> bool([])
False
>>> not []
True
>>> class MyFalsey(object):
... def __bool__(self):
... return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True
Bu nedenle, değişkenleri aşağıdaki şekilde test ederken, teste neleri dahil ettiğiniz veya testin dışında bıraktığınız konusunda daha fazla bilgi sahibi olun:
def some_function(value=None):
if not value:
value = init_value()
Yukarıda, init_value()değer özellikle olarak ayarlandığında çağırmak Nonemı istediniz 0, yoksa boş bir dize olarak ayarlanmış bir değer mi yoksa boş bir liste mi yoksa boş bir listenin de başlatmayı tetiklemesi gerektiğini mi kastettiniz ? Dediğim gibi, dikkatli ol. Python'da açıkça olduğu gibi genellikle örtük olmaktan iyidir .
None uygulamadaNone sinyal değeri olarak kullanılırNonePython'da özel bir statüye sahiptir. Bu, favori bir temel değerdir, çünkü birçok algoritma bunu olağanüstü bir değer olarak görür. Bu tür senaryolarda, bir koşulun bazı özel işlem gerektirdiğini (varsayılan değerin ayarlanması gibi) işaret etmek için bir bayrak olarak kullanılabilir.
NoneBir işlevin anahtar kelime bağımsız değişkenlerine atayabilir ve sonra bunu açıkça test edebilirsiniz.
def my_function(value, param=None):
if param is None:
# do something outrageous!
Bir nesnenin özniteliğine ulaşmaya çalışırken varsayılan olarak döndürebilir ve daha sonra özel bir şey yapmadan önce açıkça test edebilirsiniz.
value = getattr(some_obj, 'some_attribute', None)
if value is None:
# do something spectacular!
Var olmayan bir anahtara erişmeye çalışırken varsayılan olarak bir sözlüğün get()yöntemi döndürülür None:
>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True
Abonelik notasyonunu kullanarak erişmeye KeyErrorçalışsaydınız a
>>> value = some_dict['foo']
KeyError: 'foo'
Benzer şekilde, var olmayan bir öğeyi açmaya çalışırsanız
>>> value = some_dict.pop('foo')
KeyError: 'foo'
Genellikle varsayılan olarak ayarlanmış varsayılan bir değerle bastırabileceğiniz None
value = some_dict.pop('foo', None)
if value is None:
# booom!
None hem bayrak hem de geçerli değer olarak kullanılırYukarıda açıklanan kullanımları, Nonegeçerli bir değer olarak kabul edilmediğinde, daha çok özel bir şey yapmak için bir sinyal gibi olduğunda geçerlidir. Ancak bazen nereden Nonegeldiğini bilmenin önemli olduğu durumlar vardır, çünkü bir sinyal olarak kullanılmasına rağmen verilerin bir parçası da olabilir.
Bir nesneyi getattr(some_obj, 'attribute_name', None)geri alma ile Noneözniteliği sorguladığınızda, erişmeye çalıştığınız özniteliğin ayarlanmış olup Noneolmadığını veya nesnede tamamen bulunmadığını bildirmez . Gibi bir sözlükten bir anahtara erişirken aynı durum , eksik olup olmadığını veya sadece olarak ayarlanmış olup some_dict.get('some_key')olmadığını bilmiyorsunuz . Bu bilgiye ihtiyacınız varsa, bunu ele almanın genel yolu, bir yapı içinden öznitelik veya anahtara doğrudan erişmeye çalışmaktır :some_dict['some_key']Nonetry/except
try:
# equivalent to getattr() without specifying a default
# value = getattr(some_obj, 'some_attribute')
value = some_obj.some_attribute
# now you handle `None` the data here
if value is None:
# do something here because the attribute was set to None
except AttributeError:
# we're now hanling the exceptional situation from here.
# We could assign None as a default value if required.
value = None
# In addition, since we now know that some_obj doesn't have the
# attribute 'some_attribute' we could do something about that.
log_something(some_obj)
Benzer şekilde:
try:
value = some_dict['some_key']
if value is None:
# do something here because 'some_key' is set to None
except KeyError:
# set a default
value = None
# and do something because 'some_key' was missing
# from the dict.
log_something(some_dict)
Yukarıdaki iki örnek, nesne ve sözlük vakalarının nasıl ele alınacağını gösterir, ya fonksiyonlar? Aynı şey, ancak bu amaçla double asterisks anahtar kelime argümanını kullanıyoruz:
def my_function(**kwargs):
try:
value = kwargs['some_key']
if value is None:
# do something because 'some_key' is explicitly
# set to None
except KeyError:
# we assign the default
value = None
# and since it's not coming from the caller.
log_something('did not receive "some_key"')
None yalnızca geçerli bir değer olarak kullanılırEğer try/exceptsadece Nonebayraklar ve Noneveriler arasında ayrım yapmak için kodunuzun yukarıdaki desenle dolu olduğunu fark ederseniz , sadece başka bir test değeri kullanın. Bir veri yapısındaki verilerin bir parçası olarak geçerli değerler kümesinin dışında kalan bir değerin eklendiği ve özel koşulları (ör. Sınırlar, durum vb.) Kontrol etmek ve test etmek için kullanıldığı bir model vardır. Böyle bir değere bir sentinel denir ve Nonebir sinyal olarak kullanılan şekilde kullanılabilir. Python'da bir nöbetçi oluşturmak önemsizdir.
undefined = object()
Yukarıdaki undefinednesne benzersizdir ve bir programın ilgisini çekebilecek hiçbir şey yapmaz, bu nedenle Nonebayrak olarak mükemmel bir alternatiftir . Bazı uyarılar geçerlidir, daha sonra koddan sonra.
Fonksiyonu ile
def my_function(value, param1=undefined, param2=undefined):
if param1 is undefined:
# we know nothing was passed to it, not even None
log_something('param1 was missing')
param1 = None
if param2 is undefined:
# we got nothing here either
log_something('param2 was missing')
param2 = None
Dikte ile
value = some_dict.get('some_key', undefined)
if value is None:
log_something("'some_key' was set to None")
if value is undefined:
# we know that the dict didn't have 'some_key'
log_something("'some_key' was not set at all")
value = None
Bir nesne ile
value = getattr(obj, 'some_attribute', undefined)
if value is None:
log_something("'obj.some_attribute' was set to None")
if value is undefined:
# we know that there's no obj.some_attribute
log_something("no 'some_attribute' set on obj")
value = None
Daha önce de belirttiğim gibi, özel nöbetçiler bazı uyarılarla birlikte gelir. İlk olarak, bunlar gibi anahtar kelimeler değildir None, bu nedenle python onları korumaz. undefinedYukarıda tanımladığınız modülde herhangi bir yerde yukarıdakilerin üzerine yazabilirsiniz , bu yüzden bunları nasıl açığa çıkardığınıza ve kullandığınıza dikkat edin. Daha sonra, döndürülen örnek object()tekil değildir, bu çağrıyı 10 kez yaparsanız 10 farklı nesne elde edersiniz. Son olarak, bir nöbetçi kullanımı oldukça kendine özgüdür. Bir sentinel, kullanıldığı kütüphaneye özgüdür ve bu nedenle kapsamı genellikle kütüphanenin içi ile sınırlı olmalıdır. Dışarı sızmamalı. Harici kod, yalnızca amacı kütüphanenin API'sini genişletmek veya desteklemekse farkında olmalıdır.
Diğer dillerde olduğu gibi null olarak adlandırılmaz, ancak None. Bu nesnenin her zaman yalnızca bir örneği vardır, bu nedenle isterseniz x is Noneyerine (kimlik karşılaştırması) ile eşdeğer olup olmadığını kontrol edebilirsiniz x == None.
None. O zaman karşılaştırma yapan tüm zeki insanlar NoneTypezafer kazanacak!
Python'da, bir değerin yokluğunu temsil etmek için nesneler için Yok değerini ( types.NoneType.None ) ve dizeler için "" (veya len () == 0 ) kullanabilirsiniz. Bu nedenle:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
"==" ve "is" arasındaki farkla ilgili olarak, "==" kullanarak nesne kimliği testi yeterli olmalıdır. Ancak, "is" işlemi nesne kimliği işlemi olarak tanımlandığından, "==" yerine onu kullanmak daha doğru olur. Hız farkı bile olup olmadığından emin değilim.
Her neyse, şunlara göz atabilirsiniz:
0 == falsedöner trueoperatör tipi zorlama yapar çift eşittir çünkü. Bununla birlikte, üçlü eşit işleçle, 'sayı' ve 'boole' farklı türler olduğu için 0 === falsegeri döner false.
truekoşullu olarak değerlendirilir. Rust ve Go'da 0ve false eşitlikle karşılaştırılamayan farklı türlerdir.
Null, aşağıdaki gibi özel bir nesne türüdür:
>>>type(None)
<class 'NoneType'>
Bir nesnenin 'NoneType' sınıfında olup olmadığını kontrol edebilirsiniz:
>>>variable = None
>>>variable is None
True
Daha fazla bilgi Python Docs adresinde mevcuttur.
Başına Gerçek değer testi basit ifadesi yeterli olacaktır böylece, 'Yok' doğrudan false olarak test eder:
if not foo:
Trueiçin geri dönecektir . None
egg is Noneüzerindeegg == None: ikincisi (öyle mi, nasıl uygulandığı bağlıdır, ancak herkesin dikkate None ile karşılaştırmalar almaya sanmıyoruz?) Aşırı ve Hiçbiri ile geçerli nesneyi karşılaştırırken bozulma olasılığı bulunuyor olabilir ,isher zaman aynı şekilde çalışır.