Bagaimana cara mengubah Nonetype menjadi int atau string?

99

Saya punya Nonetypenilai x, umumnya angka, tapi bisa jadi None. Saya ingin membaginya dengan angka, tetapi Python memunculkan:

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

Bagaimana saya bisa memecahkan masalah ini?

pengguna469652
sumber
5
Asumsikan bahwa None sama dengan 2771. Tetapi mungkin bukan itu yang Anda inginkan. Tolong beri informasi lebih lanjut.
JoshD
Entah bagaimana saya mendapat nilai Nonetype, itu seharusnya int, tapi sekarang menjadi objek Nonetype, dan saya perlu membagi nomor lain, lalu muncul kesalahan.
pengguna469652
int(None)melempar pengecualian karena Tidak Ada tidak bisa diubah menjadi int. Jawaban atas pertanyaan Anda tidak bisa dilakukan. Anda dapat mengganti sesuatu, seperti 0, atau 2771, atau gajah merah muda, tetapi apa pun yang Anda gantikan, Anda tetap tidak dapat mengonversi Tidak Ada menjadi int.
snapshoe
7
@ muhammad.h mengonversi Nonemenjadi gajah merah muda juga tidak baik, kecuali Anda mengerjakan beberapa sistem bilangan yang secara resmi mendefinisikan pembagian angka dengan gajah merah muda (dan Anda telah menulis kode untuk mendukungnya)
aaronasterling

Jawaban:

50

Di salah satu komentar, Anda berkata:

Entah bagaimana saya mendapat nilai Nonetype, seharusnya int, tapi sekarang menjadi objek Nonetype

Jika itu kode Anda, cari tahu bagaimana Anda mendapatkan Noneketika Anda mengharapkan nomor dan hentikan itu terjadi.

Jika itu adalah kode orang lain, cari tahu kondisi yang diberikan Nonedan tentukan nilai yang masuk akal untuk digunakan untuk itu, dengan kode bersyarat biasa:

result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

...atau bahkan...

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.

Tidak ada alasan untuk secara otomatis menggunakan di 0sini - solusi yang bergantung pada "palsu" - Noneanggapan Anda akan menginginkan ini. Itu DEFAULT_VALUE(bahkan jika ada) sepenuhnya tergantung pada tujuan kode Anda.

detly
sumber
5
1 untuk solusi yang "tepat". Jika jendela Anda sering pecah secara misterius, cari tahu mengapa (dan tangkap perusak yang bertanggung jawab) daripada memblokir jendela;)
3
Ini tidak berguna jika Anda mengambil kunci dari kamus redis misalnya, karena kunci yang hilang adalah None. Jika Anda ingin menjumlahkan mereka terlepas dari keberadaan mereka (yang merupakan perilaku yang dapat diterima sepenuhnya), Anda mungkin perlu mengubah Tidak Ada menjadi 0 (lihat jawaban kindall)
laba
1
@spider - itu berarti masih sangat tergantung pada situasi, dan "menentukan nilai yang masuk akal" masih berlaku.
detly
Poin laba-laba cukup valid, jawaban ini pada dasarnya hanya mengatakan Anda melakukan sesuatu yang salah, tetapi Tidak ada tidak berarti bahwa itu berarti nilai yang tidak diketahui, yang dapat menunjukkan Anda melakukan sesuatu yang salah, atau ketika laba-laba menyarankan nilai yang hilang, secara umum itu harus 0 atau mungkin 1, untuk sebagian besar kemungkinan penggunaan None di mana diharapkan bilangan bulat.
Glen Fletcher
@glenflet Jika Anda tidak tahu apa domain input dan spesifikasi fungsi Anda, orang asing di internet tidak akan dapat memberi tahu Anda. Jika Anda tahu, tetapi tidak tahu sintaks untuk mengubahnya, itu adalah pertanyaan yang sama sekali berbeda dengan yang ditanyakan di sini.
detly
318
int(value or 0)

Ini akan menggunakan 0 jika Anda memberikan nilai apa pun yang dipertimbangkan Python False, seperti None, 0, [], "", dll. Karena 0 adalah False, Anda sebaiknya hanya menggunakan 0 sebagai nilai alternatif (jika tidak, Anda akan menemukan 0 berubah menjadi nilai itu).

int(0 if value is None else value)

Ini hanya menggantikan Nonedengan 0. Karena kami menguji secara Nonekhusus, Anda dapat menggunakan beberapa nilai lain sebagai penggantinya.

kindall
sumber
65
user469652 Anda harus mempertimbangkan untuk menjadikan ini sebagai jawaban yang diterima. sebenarnya membantu daripada merendahkan
galarant
Saya tidak yakin apakah ini menyelesaikan masalah yang dihadapi pengguna yaitu. gunakan nonetype untuk melakukan kalkulasi ... saat ini saya menarik data melalui rest api yang mengembalikan nonetype yang berisi nilai numerik. Jika saya mengaturnya ke 0 atau membiarkannya seperti itu saya tidak dapat melakukan apa pun dengannya
br3w5
2
Ini jelas merupakan jawaban terbaik, mengingat pertanyaannya, karena pengguna menunjukkan bahwa Tidak Ada, harus diharapkan, seperti kemungkinan fungsi, meminta nilai dari sesuatu yang mengembalikan Tidak ada untuk menunjukkan nilai tidak diketahui dalam hal ini Tidak ada harus menjadi nilai default dalam kasus penggunaannya, yang biasanya 0. pertimbangkan izip_longest, argumen default, jika yang berbeda memiliki default yang berbeda (tipe genap), maka defaultnya harus None yang kemudian diganti dengan default, namun string. <align_n> (str, w) hanya membutuhkan bilangan bulat untuk lebarnya.
Glen Fletcher
2
Menggunakan ini dan itu elegan dan memecahkan masalah saya.
Dan Safee
1
kita dapat menggunakan (value or 0)- tanpa pengecoran tipe int - jika kita yakin bahwa nilainya hanya dapat berupa None atau int
hashlash
17

Cara umum "Pythonic" untuk menangani situasi semacam ini dikenal sebagai EAFP untuk " Lebih mudah meminta maaf daripada izin ". Yang biasanya berarti menulis kode yang mengasumsikan semuanya baik-baik saja, tetapi kemudian membungkusnya dengan try...exceptblok untuk menangani berbagai hal — untuk berjaga-jaga — ternyata tidak.

Inilah gaya pengkodean yang diterapkan pada masalah Anda:

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

answer = my_value / divisor

Atau mungkin yang lebih sederhana dan sedikit lebih cepat:

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

Pendekatan terbalik dan yang lebih tradisional dikenal sebagai LBYL yang merupakan singkatan dari " Lihat sebelum Anda melompat " adalah apa yang disarankan oleh @Soviut dan beberapa yang lain. Untuk cakupan tambahan topik ini lihat jawaban saya dan komentar terkait untuk pertanyaan Menentukan apakah kunci ada dalam kamus di tempat lain di situs ini.

Salah satu potensi masalah dengan EAFP adalah ia dapat menyembunyikan fakta bahwa ada sesuatu yang salah dengan beberapa bagian lain dari kode Anda atau modul pihak ketiga yang Anda gunakan, terutama ketika pengecualian sering terjadi (dan karenanya bukan kasus yang benar-benar "luar biasa" sama sekali).

martineau.dll
sumber
11

Itu TypeErrorhanya muncul ketika Anda mencoba untuk lulus int() None(yang merupakan satu-satunya NoneTypenilai, sejauh yang saya tahu). Saya akan mengatakan bahwa tujuan Anda yang sebenarnya seharusnya tidak mengonversi NoneTypemenjadi intatau str, tetapi untuk mencari tahu di mana / mengapa Anda mendapatkan Nonealih-alih angka seperti yang diharapkan, dan memperbaikinya atau menanganinya dengan Nonebenar.

paradoks wafel
sumber
Meneruskan int()bilangan kompleks, seperti int(1+2j), juga akan menyebabkan a TypeErrordinaikkan, meskipun diakui hal itu mungkin sangat tidak mungkin. Terlepas dari itu, saya pikir Anda berkata akan, tanpa pertanyaan, umumnya nasihat yang baik untuk diikuti.
martineau
5

Di Python 3, Anda juga dapat menggunakan kata kunci "atau". Cara ini:

foo = bar or 0
foo2 = bar or ""
Ferrarezi
sumber
2

Saya telah berhasil menggunakan int (x atau 0) untuk jenis kesalahan ini, selama Tidak Ada harus sama dengan 0 dalam logika. Perhatikan bahwa ini juga akan menyelesaikan ke 0 dalam kasus lain di mana pengujian x mengembalikan False. misalnya daftar kosong, set, kamus atau string panjang nol. Maaf, Kindall sudah memberikan jawaban ini.

pengguna3109122
sumber
1

Ini bisa terjadi jika Anda lupa mengembalikan nilai dari suatu fungsi: kemudian mengembalikan None. Lihat semua tempat di mana Anda menetapkan ke variabel itu, dan lihat apakah salah satunya adalah pemanggilan fungsi di mana fungsinya tidak memiliki pernyataan return.

Jouni K. Seppänen
sumber
1
... atau fungsi tersebut memiliki satu atau beberapa pernyataan kembalian yang sederhana, returnbukan return some_expression.
John Machin
... atau fungsi berisi satu atau lebih return Nonepernyataan
John Machin
1

Anda harus memeriksa untuk memastikan nilainya bukan None sebelum mencoba melakukan penghitungan apa pun padanya:

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

Catatan: my_value sengaja disetel ke Tidak Ada untuk membuktikan kode berfungsi dan bahwa pemeriksaan sedang dilakukan.

Soviut
sumber
1
Anda harus menggunakan perbandingan identitas ( is [not] None)
shylent
-4 Anda harus mendorong OP untuk mencari tahu apa masalah sebenarnya daripada menghindarinya. Apa yang dikatakan @ylent. Anda menyetel my_valuetanpa syarat ke Tidak Ada; Mengapa? Anda tidak mempertanyakan mengapa OP berpikir dia perlu melakukan int(my_value)padahal my_value(jika tidak ada) "umumnya angka".
John Machin
1
Saya mengatur my_value ke None sebagai bukti konsep, untuk menunjukkan kode saya tidak gagal. Saya tidak mempertanyakan OP karena ada banyak alasan mengapa suatu nilai tidak selalu berupa angka dan memeriksa bahwa nilainya sebelum melakukan perhitungan adalah ide yang bagus. Tidak ada salahnya menjawab pertanyaan OP saja, saya tidak harus mengerjakan semua PR untuk mereka.
Soviut
1

Saya mengalami masalah yang sama menggunakan fungsi email python. Di bawah ini adalah kode yang saya coba untuk mengambil subjek email ke dalam variabel. Ini berfungsi dengan baik untuk sebagian besar email dan variabel terisi. Jika Anda menerima email dari Yahoo atau sejenisnya dan pengirim tidak mengisi baris subjek, Yahoo tidak membuat baris subjek di email dan Anda mendapatkan NoneType yang dikembalikan dari fungsi tersebut. Martineau memberikan jawaban yang benar seperti halnya Soviut. Jawaban IMO Soviut lebih ringkas dari segi pemrograman; belum tentu dari Python. Berikut beberapa kode untuk menunjukkan tekniknya:

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()
George Pearson
sumber
1

Dalam beberapa situasi, sebaiknya memiliki fungsi untuk mengonversi None menjadi int zero:

def nz(value):

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

    if value == None:
        return 0
    return value
pengguna2920482
sumber