Nonetype'ı int veya string'e nasıl dönüştürebilirim?


102

Bir var Nonetypebir değer xgenellikle bir numarası, ama olabilir, None. Bunu bir sayıya bölmek istiyorum, ancak Python şunu yükseltir:

TypeError: int() argument must be a string or a number, not 'NoneType'

Bunu Nasıl Çözebilirim?


5
Hiçbiri'nin 2771'e eşdeğer olduğunu varsayın. Ama belki de istediğiniz bu değildir. Lütfen daha fazla bilgi veriniz.
JoshD

Bir şekilde bir Nonetype değeri aldım, bunun bir int olması gerekiyordu, ama şimdi bir Nonetype nesnesi ve başka bir sayıyı bölmem gerekiyor, sonra hata ortaya çıktı.
user469652

int(None)Hiçbiri bir int'e dönüştürülemediğinden bir istisna atar. Sorunuzun cevabı yapılamaz. 0 veya 2771 gibi bir şeyi veya pembe bir filin yerine koyabilirsiniz, ancak ne koyarsanız koyun, yine de Hiçbirini int'e dönüştüremezsiniz.
17'de snapshoe

7
@ ma3204. dönüştürme NoneEğer resmen pembe bir fil bir dizi bölünmesini tanımlar bazı sayı sistemini çalışmadığınız sürece hiçbir iyi, ya pembe fil için (ve bunu yedeklemek için kod yazdım)
aaronasterling

Yanıtlar:


50

Yorumlardan birinde şöyle diyorsunuz:

Bir şekilde bir Nonetype değeri aldım, bunun bir int olması gerekiyordu, ancak artık bir Nonetype nesnesi

Bu senin kod, figür alıyoruz nasıl olursa Nonebir numara ve durmasını bekliyoruz zaman olduğu gelen oluyor.

Başkasının koduysa, bunun için verdiği koşulları öğrenin Noneve her zamanki koşullu kodla bunun için kullanılacak mantıklı bir değer belirleyin:

result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

...ya da...

if x == THING_THAT_RESULTS_IN_NONE:
    result = DEFAULT_VALUE
else:
    result = could_return_none(x) # But it won't return None, because we've restricted the domain.

Burada otomatik olarak kullanmak için bir neden 0yok - Nonebunu isteyeceğinizi varsaymanın "yanlış "lığına bağlı çözümler . DEFAULT_VALUE(Hatta varsa) tamamen kodun amacına bağlıdır.


5
"Doğru" çözüm için +1. Pencereniz genellikle gizemli bir şekilde kırılıyorsa, pencereyi kapatmak yerine nedenini bulun (ve sorumlu olan

3
Örneğin, anahtarları bir redis sözlüğünden alıyorsanız bu yararlı değildir, çünkü eksik anahtarlar Yok olacaktır. Onları mevcudiyetlerinden bağımsız olarak özetlemek istiyorsanız (ki bu tamamen kabul edilebilir bir davranıştır), Yok'u 0'a çevirmeniz gerekebilir (lütfen cevaba bakın)
örümcek

1
@spider - bu, duruma oldukça bağlı olduğu anlamına gelir ve "mantıklı bir değer belirleme" hala geçerlidir.
detly

Örümcek'in noktası oldukça geçerli Bu cevap temelde sadece yanlış bir şey yaptığınızı söylüyor, ancak Hiçbiri bunun bilinmeyen bir değer anlamına gelmediği, yanlış bir şey yaptığınızı gösterebileceği veya örümcek eksik bir değeri önerdiği gibi, genel olarak 0 olması gerektiği anlamına gelmez. Bir tamsayının beklendiği yerlerde Yok seçeneğinin çoğu olası kullanımı için 1 veya 1 olabilir.
Glen Fletcher

@glenflet İşlevinizin giriş alanının ve spesifikasyonunun ne olduğunu bilmiyorsanız, internetteki bir yabancı size söyleyemez. Biliyorsanız, ancak onu dönüştürmek için sözdizimini bilmiyorsanız, bu burada sorulandan tamamen farklı bir sorudur.
detly

324
int(value or 0)

FalseHiçbiri, 0, [], "" vb. Gibi Python tarafından kabul edilen herhangi bir değeri girdiğinizde bu 0'ı Falsekullanacaktır. 0 olduğundan, alternatif değer olarak yalnızca 0 kullanmalısınız (aksi takdirde 0'larınızı bu değere dönüşüyor).

int(0 if value is None else value)

Bu, yalnızca None0 ile değiştirilir . NoneÖzel olarak test ettiğimiz için , değiştirme olarak başka bir değer kullanabilirsiniz.


66
user469652 bunun yerine bunu kabul edilen cevap olarak düşünmelisiniz. küçümsemek yerine aslında yararlı
galarant

Bunun kullanıcının karşılaştığı sorunu çözüp çözmediğinden emin değilim. bir hesaplama yapmak için nonetype kullanın ... Şu anda verileri sayısal bir değer içeren nonetype döndüren bir rest api aracılığıyla çekiyorum. 0 olarak ayarlarsam veya olduğu gibi bırakırsam onunla hiçbir şey
yapamam

2
Bu, soruya verilen en iyi cevaptır, çünkü kullanıcı muhtemelen bir işlev gibi Hiçbiri'nin beklenmelidir, değerin bilinmediğini belirtmek için Yok döndüren bir şeyin değerini talep eder, bu durumda Yok varsayılan değer olmalıdır kullanım durumunda, ki bu genellikle 0 olacaktır. izip_longest, varsayılan argümanı düşünün, farklı olanın farklı bir varsayılanı (çift türü) vardır, o zaman varsayılan Yok olmalıdır ve bu durumda bir varsayılan, ancak dizeyle değiştirilir. <align_n> (str, w) yalnızca genişlik için bir tamsayı alır.
Glen Fletcher

3
Bunu kullandım ve zarifti ve sorunlarımı çözdü.
Dan Safee

1
Kullanabileceğimiz (value or 0)- int tipi döküm olmadan - biz bu değer sadece bir Hiçbiri ya da int olabilir emin eğer
hashlash

17

Bu tür durumlarla başa çıkmanın yaygın bir "Pythonic" yolu, " Af dilemek izin istemekten daha kolaydır " için EAFP olarak bilinir . Bu da genellikle her şeyin yolunda olduğunu varsayan bir kod yazmak anlamına gelir, ancak daha sonra her şeyi işlemek için bir blokla sarmak - her ihtimale karşı - değildir.try...except

İşte probleminize uygulanan kodlama stili:

try:
    my_value = int(my_value)
except TypeError:
    my_value = 0  # or whatever you want to do

answer = my_value / divisor

Ya da belki daha basit ve biraz daha hızlı:

try:
    answer = int(my_value) / divisor
except TypeError:
    answer = 0

Ters ve daha geleneksel yaklaşım, @Soviut ve diğerlerinin önerdiği, "Atlamadan önce bak " anlamına gelen LBYL olarak bilinir . Bu konuyla ilgili daha fazla bilgi için cevabıma ve soruyla ilgili yorumlara bakın Bu sitenin başka bir yerinde bir sözlükte bir anahtar bulunup bulunmadığını belirleyin .

EAFP ile ilgili olası bir sorun, kodunuzun başka bir bölümünde veya kullandığınız üçüncü taraf modülünde, özellikle de istisnalar sık ​​sık ortaya çıktığında (ve bu nedenle gerçekten "istisnai" durumlar olmadığında) bir şeylerin yanlış olduğu gerçeğini gizleyebilmesidir. hiç).


11

Bu TypeErrorsadece geçmeye çalıştığınızda görünür int() None( NoneTypebildiğim kadarıyla tek değer budur). Senin gerçek hedef dönüştürün olmaması gerektiğini söyleyebilirim NoneTypeiçin intya strama niye alıyoruz nerede / anlamaya Nonebeklendiği gibi bir numara yerine, ve bunu düzeltmek veya işlemek ya Nonedüzgün.


Geçme int()gibi bir kompleks sayı int(1+2j), aynı zamanda bir neden olur TypeError, yetiştirilmek üzere kuşkusuz muhtemelen çok olası olduğunu rağmen. Her şeye rağmen, soru sormadan, genellikle uyulması gereken iyi bir tavsiye olacağını söylediğinizi düşünüyorum.
martineau

5

Python 3'te "veya" anahtar kelimesini de kullanabilirsiniz. Bu yoldan:

foo = bar or 0
foo2 = bar or ""

2

Hiçbiri mantıkta 0'a eşit olması gerektiği sürece, bu tür bir hata için başarıyla int (x veya 0) kullandım. Bunun, x testinin False döndürdüğü diğer durumlarda da 0'a çözümleneceğini unutmayın. örneğin boş liste, küme, sözlük veya sıfır uzunluklu dizge. Üzgünüm, Kindall bu cevabı zaten verdi.


1

Bu, bir işlevden bir değer döndürmeyi unutursanız gerçekleşebilir: ardından Hiçbiri döndürür. Bu değişkene atadığınız tüm yerlere bakın ve bunlardan birinin, işlevin return deyiminin olmadığı bir işlev çağrısı olup olmadığına bakın.


1
... veya işlevin returnyerine düz olan bir veya daha fazla dönüş ifadesi vardır return some_expression.
John Machin

... veya işlev bir veya daha fazla return Noneifade içeriyor
John Machin

1

Üzerinde herhangi bir hesaplama yapmaya çalışmadan önce değerin Yok olmadığından emin olmalısınız :

my_value = None
if my_value is not None:
    print int(my_value) / 2

Not: my_value kodun çalıştığını ve denetimin gerçekleştirildiğini kanıtlamak için kasıtlı olarak Yok olarak ayarlanmıştır.


1
kimlik karşılaştırmasını kullanmalısınız ( is [not] None)
shylent

-4 OP'yi, ondan kaçınmak yerine gerçek sorununun ne olduğunu bulması için cesaretlendirmelisiniz. @Shylent ne dedi. my_valueKoşulsuz olarak Yok olarak ayarladınız ; neden? OP'nin neden (Yok değilse) "genellikle bir sayı" int(my_value)olduğunda yapması gerektiğini düşündüğünü sorgulamıyorsunuz my_value.
John Machin

1
Kodumun başarısız olmadığını göstermek için kavramın bir kanıtı olarak my_value'umu Yok olarak ayarladım. OP'yi sorgulamadım çünkü bir değerin her zaman bir sayı olmamasının birçok nedeni vardır ve hesaplamaları yapmadan önce bunun kontrol edilmesi iyi bir fikirdir. Sadece OP'nin sorusunu cevaplamakta yanlış bir şey yok, onlar için tüm ev ödevlerini yapmak zorunda değilim.
Soviut

1

Python e-posta işlevlerini kullanırken aynı sorunu yaşıyordum. E-posta konusunu bir değişkene almaya çalıştığım kod aşağıdadır. Bu, çoğu e-posta ve değişken popülasyonları için iyi çalışır. Yahoo veya benzerinden bir e-posta alırsanız ve gönderen konu satırını doldurmadıysa, Yahoo e-postada bir konu satırı oluşturmaz ve işlevden dönen bir NoneType alırsınız. Martineau, Soviut kadar doğru bir cevap verdi. IMO Soviut'un cevabı, programlama açısından daha özlüdür; bir Python'dan değil. Tekniği göstermek için bazı kodlar:

import sys, email, email.Utils 

afile = open(sys.argv[1], 'r')    
m = email.message_from_file(afile)    
subject = m["subject"]

# Soviut's Concise test for unset variable.

if subject is None:    
     subject = "[NO SUBJECT]"

# Alternative way to test for No Subject created in email (Thanks for NoneThing Yahoo!)

try:    
    if len(subject) == 0:    
        subject = "[NO SUBJECT]"

except TypeError:    
    subject = "[NO SUBJECT]"

print subject

afile.close()

1

Bazı durumlarda, Yok'u int sıfıra dönüştürmek için bir işleve sahip olmak yararlıdır:

def nz(value):

    '''
    Convert None to int zero else return value.
    '''

    if value == None:
        return 0
    return value
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.