วิธีการแปลง Nonetype เป็น int หรือ string


99

ฉันมีNonetypeค่าxโดยทั่วไปแล้วจะเป็นตัวเลข แต่อาจเป็นNoneได้ ฉันต้องการหารด้วยตัวเลข แต่ Python เพิ่ม:

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

ฉันจะแก้ปัญหานี้ได้อย่างไร?


5
สมมติว่าไม่มีเทียบเท่ากับ 2771 แต่นั่นอาจไม่ใช่สิ่งที่คุณต้องการ กรุณาให้ข้อมูลเพิ่มเติม
JoshD

อย่างไรก็ตามฉันได้ค่า Nonetype มันควรจะเป็น int แต่ตอนนี้มันเป็นวัตถุ Nonetype และฉันต้องหารตัวเลขอื่นจากนั้นข้อผิดพลาดก็เกิดขึ้น
user469652

int(None)แสดงข้อยกเว้นเนื่องจากไม่มีไม่สามารถแปลงเป็น int คำตอบสำหรับคำถามของคุณคือไม่สามารถทำได้ คุณสามารถแทนที่บางอย่างเช่น 0 หรือ 2771 หรือช้างสีชมพู แต่ไม่ว่าคุณจะแทนที่อะไรคุณก็ยังไม่สามารถแปลง None เป็น int ได้
snapshoe

7
@ ma3204. การแปลงNoneเป็นช้างสีชมพูก็ไม่ดีเช่นกันเว้นแต่คุณจะใช้ระบบตัวเลขที่กำหนดการหารตัวเลขอย่างเป็นทางการด้วยช้างสีชมพู (และคุณได้เขียนรหัสเพื่อสำรองไว้)
aaronasterling

คำตอบ:


50

ในความคิดเห็นหนึ่งคุณพูดว่า:

อย่างไรก็ตามฉันได้รับค่า Nonetype มันควรจะเป็น int แต่ตอนนี้มันเป็นวัตถุ Nonetype

หากเป็นรหัสของคุณให้หาวิธีที่คุณได้รับNoneเมื่อคุณคาดหวังตัวเลขและหยุดไม่ให้เกิด

หากเป็นรหัสของผู้อื่นให้ค้นหาเงื่อนไขที่Noneระบุและกำหนดค่าที่เหมาะสมที่จะใช้สำหรับสิ่งนั้นด้วยรหัสเงื่อนไขตามปกติ:

result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

...หรือแม้กระทั่ง...

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.

ไม่มีเหตุผลที่จะใช้0ที่นี่โดยอัตโนมัติ- โซลูชันที่ขึ้นอยู่กับ "เท็จ" ของNoneสมมติฐานที่คุณต้องการสิ่งนี้ DEFAULT_VALUE(ถ้ามันยังมีอยู่) อย่างสมบูรณ์ขึ้นอยู่กับวัตถุประสงค์ของรหัสของคุณ


5
+1 สำหรับโซลูชันที่ "ถูกต้อง" หากหน้าต่างของคุณแตกอย่างลึกลับบ่อยครั้งให้หาสาเหตุ (และจับคนป่าเถื่อนว่าใครเป็นผู้รับผิดชอบ) แทนที่จะปิดกั้นหน้าต่าง;)

3
สิ่งนี้ไม่มีประโยชน์ในกรณีที่คุณกำลังดึงคีย์จากพจนานุกรม redis เช่นคีย์ที่หายไปจะเป็นไม่มี หากคุณต้องการสรุปโดยไม่คำนึงถึงการปรากฏตัวของพวกเขา (ซึ่งเป็นพฤติกรรมที่ยอมรับได้โดยสิ้นเชิง) คุณอาจต้องแปลง None เป็น 0 (ดูคำตอบ)
แมงมุม

1
@spider - นั่นยังคงหมายความว่าขึ้นอยู่กับสถานการณ์เป็นอย่างมากและยังคงใช้ "กำหนดมูลค่าที่สมเหตุสมผล"
ด่วน

ประเด็นของแมงมุมค่อนข้างถูกต้องคำตอบนี้โดยทั่วไปเพียงแค่บอกว่าคุณทำอะไรผิด แต่ไม่มีไม่ได้หมายความว่ามันหมายถึงค่าที่ไม่รู้จักนั่นอาจบ่งบอกว่าคุณทำอะไรผิดพลาดหรือเนื่องจากแมงมุมแนะนำค่าที่ขาดหายไปโดยทั่วไปควรเป็น 0 หรืออาจเป็น 1 สำหรับการใช้งานส่วนใหญ่ที่เป็นไปได้ในที่ที่คาดว่าจะมีจำนวนเต็ม
Glen Fletcher

@glenflet หากคุณไม่ทราบว่าโดเมนอินพุตและข้อมูลจำเพาะของฟังก์ชันของคุณคืออะไรคนแปลกหน้าบนอินเทอร์เน็ตจะไม่สามารถบอกคุณได้ หากคุณรู้ แต่ไม่ทราบไวยากรณ์สำหรับการแปลงนั่นเป็นคำถามที่แตกต่างอย่างสิ้นเชิงกับคำถามที่ถามที่นี่
ตั้งแต่

318
int(value or 0)

ซึ่งจะใช้ 0 ในกรณีที่คุณระบุค่าใด ๆ ที่ Python พิจารณาFalseเช่น None, 0, [], "" เป็นต้นเนื่องจาก 0 คือFalseคุณควรใช้ 0 เป็นค่าทางเลือกเท่านั้น (มิฉะนั้นคุณจะพบ 0 ของคุณ เปลี่ยนเป็นค่านั้น)

int(0 if value is None else value)

สิ่งนี้แทนที่Noneด้วย 0 เท่านั้นเนื่องจากเรากำลังทดสอบNoneโดยเฉพาะคุณสามารถใช้ค่าอื่นทดแทนได้


65
user469652 คุณควรพิจารณากำหนดให้เป็นคำตอบที่ยอมรับแทน มันมีประโยชน์จริง ๆ เมื่อเทียบกับการลดน้อยลง
galarant

ฉันไม่แน่ใจว่าวิธีนี้จะช่วยแก้ปัญหาที่ผู้ใช้เผชิญอยู่หรือไม่ ใช้ nonetype เพื่อทำการคำนวณ ... ฉันกำลังดึงข้อมูลผ่านทาง rest api ซึ่งส่งคืน nonetype ที่มีค่าตัวเลข ถ้าฉันตั้งค่าเป็น 0 หรือปล่อยไว้อย่างที่เป็นอยู่ฉันจะทำอะไรกับมันไม่ได้
br3w5

2
นี่เป็นคำตอบที่ดีที่สุดอย่างท้าทายเนื่องจากคำถามเนื่องจากผู้ใช้ระบุว่าไม่มีควรคาดหวังเช่นอาจเป็นฟังก์ชันขอค่าของสิ่งที่ส่งคืน None เพื่อระบุค่าไม่เป็นที่รู้จักในกรณีนี้ไม่มีควรกลายเป็นค่าเริ่มต้น ในกรณีการใช้งานซึ่งโดยปกติจะเป็น 0 พิจารณา izip_longest อาร์กิวเมนต์เริ่มต้นซึ่งเป็นอาร์กิวเมนต์ที่แตกต่างกันมีค่าเริ่มต้นที่แตกต่างกัน (ประเภทคู่) จากนั้นค่าเริ่มต้นควรเป็นไม่มีซึ่งจะแทนที่ด้วยค่าเริ่มต้นอย่างไรก็ตามสตริง <align_n> (str, w) ใช้จำนวนเต็มสำหรับ width เท่านั้น
Glen Fletcher

2
ใช้สิ่งนี้แล้วมันก็สวยหรูและแก้ปัญหาของฉันได้
Dan Safee

1
เราสามารถใช้ได้(value or 0)- โดยไม่ต้องแคสต์ประเภท int - หากเรามั่นใจว่าค่าสามารถเป็น None หรือ int
hashlash

17

วิธี "Pythonic" ทั่วไปในการจัดการสถานการณ์แบบนี้เรียกว่าEAFPสำหรับ " การขอการให้อภัยง่ายกว่าการอนุญาต " ซึ่งโดยปกติหมายถึงการเขียนโค้ดที่ถือว่าทุกอย่างเรียบร้อยดี แต่จากนั้นก็ห่อด้วยtry...exceptบล็อกเพื่อจัดการกับสิ่งต่างๆในกรณีที่ไม่ใช่

นี่คือรูปแบบการเข้ารหัสที่ใช้กับปัญหาของคุณ:

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

answer = my_value / divisor

หรืออาจจะง่ายกว่าและเร็วกว่าเล็กน้อย:

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

แนวทางที่ผกผันและแบบดั้งเดิมมากขึ้นเรียกว่าLBYLซึ่งย่อมาจาก " Look before you leap " คือสิ่งที่ @Soviut และคนอื่น ๆ แนะนำ สำหรับความครอบคลุมเพิ่มเติมของหัวข้อนี้โปรดดูคำตอบของฉันและความคิดเห็นที่เกี่ยวข้องกับคำถามตรวจสอบว่ามีคีย์อยู่ในพจนานุกรมที่อื่นในไซต์นี้หรือไม่

ปัญหาหนึ่งที่อาจเกิดขึ้นกับEAFPคือสามารถซ่อนความจริงที่ว่ามีบางอย่างผิดปกติกับส่วนอื่น ๆ ของโค้ดหรือโมดูลของบุคคลที่สามที่คุณใช้อยู่โดยเฉพาะอย่างยิ่งเมื่อมีข้อยกเว้นเกิดขึ้นบ่อยครั้ง (ดังนั้นจึงไม่ใช่กรณี "พิเศษ" จริงๆ เลย).


11

ที่TypeErrorจะปรากฏขึ้นเมื่อคุณพยายามที่จะผ่านint() None(ซึ่งเป็นเพียงNoneTypeค่าเท่าที่ผมรู้) ฉันจะบอกว่าเป้าหมายที่แท้จริงของคุณไม่ควรเปลี่ยนNoneTypeเป็นintหรือstrแต่เพื่อหาว่าทำไมคุณถึงได้รับNoneแทนที่จะเป็นตัวเลขตามที่คาดไว้และแก้ไขหรือจัดการNoneอย่างเหมาะสม


การส่งint()จำนวนเชิงซ้อนเช่นint(1+2j)จะทำให้เกิดการTypeErrorเพิ่มขึ้นแม้ว่าจะเป็นที่ยอมรับว่าไม่น่าจะเป็นไปได้ ไม่ว่าฉันคิดว่าคุณจะพูดโดยไม่มีคำถามโดยทั่วไปแล้วคำแนะนำที่ดีในการปฏิบัติตาม
martineau

5

ใน Python 3 คุณสามารถใช้คีย์เวิร์ด "หรือ" ได้เช่นกัน ทางนี้:

foo = bar or 0
foo2 = bar or ""

2

ฉันใช้ int (x หรือ 0) สำหรับข้อผิดพลาดประเภทนี้สำเร็จแล้วตราบใดที่ None ควรเท่ากับ 0 ในตรรกะ โปรดทราบว่าสิ่งนี้จะแก้ไขเป็น 0 ด้วยในกรณีอื่น ๆ ที่การทดสอบ x ส่งคืน False เช่นรายการว่างชุดพจนานุกรมหรือสตริงความยาวเป็นศูนย์ ขออภัย Kindall ได้ให้คำตอบนี้แล้ว


1

สิ่งนี้สามารถเกิดขึ้นได้หากคุณลืมส่งคืนค่าจากฟังก์ชันจากนั้นจะส่งคืนค่า None ดูตำแหน่งทั้งหมดที่คุณกำหนดให้กับตัวแปรนั้นและดูว่าหนึ่งในนั้นเป็นการเรียกใช้ฟังก์ชันโดยที่ฟังก์ชันไม่มีคำสั่ง return หรือไม่


1
... หรือฟังก์ชั่นมีหนึ่งหรือมากกว่างบผลตอบแทนที่เป็นเพียงธรรมดาแทนreturn return some_expression
John Machin

... หรือฟังก์ชั่นมีreturn Noneคำสั่งอย่างน้อยหนึ่งรายการ
John Machin

1

คุณควรตรวจสอบให้แน่ใจว่าค่าไม่ใช่ None ก่อนที่จะพยายามทำการคำนวณใด ๆ :

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

หมายเหตุ: my_valueถูกตั้งค่าโดยเจตนาเป็นไม่มีเพื่อพิสูจน์ว่ารหัสใช้งานได้และกำลังดำเนินการตรวจสอบ


1
คุณควรใช้การเปรียบเทียบตัวตน ( is [not] None)
shylent

-4 คุณควรให้กำลังใจ OP เพื่อค้นหาว่าปัญหาที่แท้จริงของเขาคืออะไรแทนที่จะหลีกเลี่ยงมัน @shylent พูดอะไร คุณตั้งค่าเป็นmy_valueไม่มีโดยไม่มีเงื่อนไข ทำไม? คุณไม่ต้องสงสัยว่าทำไม OP ถึงคิดว่าเขาต้องทำint(my_value)เมื่อmy_valueคือ (ถ้าไม่ใช่ไม่มี)
John Machin

1
ฉันตั้งค่า my_value เป็นไม่มีเพื่อเป็นหลักฐานยืนยันแนวคิดเพื่อแสดงว่ารหัสของฉันไม่ล้มเหลว ฉันไม่ได้ตั้งคำถามกับ OP เพราะมีหลายสาเหตุที่ค่าอาจไม่ใช่ตัวเลขเสมอไปและการตรวจสอบว่าเป็นตัวเลขก่อนที่จะทำการคำนวณเป็นความคิดที่ดี เพียงแค่ตอบคำถามของ OP ฉันไม่จำเป็นต้องทำการบ้านทั้งหมดเพื่อพวกเขา
Soviut

1

ฉันประสบปัญหาเดียวกันกับการใช้ฟังก์ชันอีเมล python ด้านล่างนี้คือรหัสที่ฉันพยายามดึงหัวเรื่องอีเมลมาเป็นตัวแปร วิธีนี้ใช้ได้ดีกับอีเมลส่วนใหญ่และตัวแปรจะเติม หากคุณได้รับอีเมลจาก Yahoo หรือสิ่งที่คล้ายกันและผู้ส่งไม่ได้กรอกหัวเรื่อง Yahoo จะไม่สร้างบรรทัดหัวเรื่องในอีเมลและคุณจะได้รับ NoneType คืนจากฟังก์ชัน Martineau ให้คำตอบที่ถูกต้องเช่นเดียวกับ Soviut คำตอบของ IMO Soviut นั้นกระชับมากขึ้นจากจุดเริ่มต้นของการเขียนโปรแกรม ไม่จำเป็นต้องมาจาก Python one นี่คือรหัสบางส่วนเพื่อแสดงเทคนิค:

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

ในบางสถานการณ์การมีฟังก์ชันในการแปลง None เป็น int zero จะเป็นประโยชน์:

def nz(value):

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

    if value == None:
        return 0
    return value
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.