ฉันมีNonetypeค่าxโดยทั่วไปแล้วจะเป็นตัวเลข แต่อาจเป็นNoneได้ ฉันต้องการหารด้วยตัวเลข แต่ Python เพิ่ม:
TypeError: int() argument must be a string or a number, not 'NoneType'
ฉันจะแก้ปัญหานี้ได้อย่างไร?
ฉันมีNonetypeค่าxโดยทั่วไปแล้วจะเป็นตัวเลข แต่อาจเป็นNoneได้ ฉันต้องการหารด้วยตัวเลข แต่ Python เพิ่ม:
TypeError: int() argument must be a string or a number, not 'NoneType'
ฉันจะแก้ปัญหานี้ได้อย่างไร?
int(None)แสดงข้อยกเว้นเนื่องจากไม่มีไม่สามารถแปลงเป็น int คำตอบสำหรับคำถามของคุณคือไม่สามารถทำได้ คุณสามารถแทนที่บางอย่างเช่น 0 หรือ 2771 หรือช้างสีชมพู แต่ไม่ว่าคุณจะแทนที่อะไรคุณก็ยังไม่สามารถแปลง None เป็น int ได้
Noneเป็นช้างสีชมพูก็ไม่ดีเช่นกันเว้นแต่คุณจะใช้ระบบตัวเลขที่กำหนดการหารตัวเลขอย่างเป็นทางการด้วยช้างสีชมพู (และคุณได้เขียนรหัสเพื่อสำรองไว้)
คำตอบ:
ในความคิดเห็นหนึ่งคุณพูดว่า:
อย่างไรก็ตามฉันได้รับค่า 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(ถ้ามันยังมีอยู่) อย่างสมบูรณ์ขึ้นอยู่กับวัตถุประสงค์ของรหัสของคุณ
int(value or 0)
ซึ่งจะใช้ 0 ในกรณีที่คุณระบุค่าใด ๆ ที่ Python พิจารณาFalseเช่น None, 0, [], "" เป็นต้นเนื่องจาก 0 คือFalseคุณควรใช้ 0 เป็นค่าทางเลือกเท่านั้น (มิฉะนั้นคุณจะพบ 0 ของคุณ เปลี่ยนเป็นค่านั้น)
int(0 if value is None else value)
สิ่งนี้แทนที่Noneด้วย 0 เท่านั้นเนื่องจากเรากำลังทดสอบNoneโดยเฉพาะคุณสามารถใช้ค่าอื่นทดแทนได้
(value or 0)- โดยไม่ต้องแคสต์ประเภท int - หากเรามั่นใจว่าค่าสามารถเป็น None หรือ int
วิธี "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คือสามารถซ่อนความจริงที่ว่ามีบางอย่างผิดปกติกับส่วนอื่น ๆ ของโค้ดหรือโมดูลของบุคคลที่สามที่คุณใช้อยู่โดยเฉพาะอย่างยิ่งเมื่อมีข้อยกเว้นเกิดขึ้นบ่อยครั้ง (ดังนั้นจึงไม่ใช่กรณี "พิเศษ" จริงๆ เลย).
ที่TypeErrorจะปรากฏขึ้นเมื่อคุณพยายามที่จะผ่านint() None(ซึ่งเป็นเพียงNoneTypeค่าเท่าที่ผมรู้) ฉันจะบอกว่าเป้าหมายที่แท้จริงของคุณไม่ควรเปลี่ยนNoneTypeเป็นintหรือstrแต่เพื่อหาว่าทำไมคุณถึงได้รับNoneแทนที่จะเป็นตัวเลขตามที่คาดไว้และแก้ไขหรือจัดการNoneอย่างเหมาะสม
int()จำนวนเชิงซ้อนเช่นint(1+2j)จะทำให้เกิดการTypeErrorเพิ่มขึ้นแม้ว่าจะเป็นที่ยอมรับว่าไม่น่าจะเป็นไปได้ ไม่ว่าฉันคิดว่าคุณจะพูดโดยไม่มีคำถามโดยทั่วไปแล้วคำแนะนำที่ดีในการปฏิบัติตาม
ใน Python 3 คุณสามารถใช้คีย์เวิร์ด "หรือ" ได้เช่นกัน ทางนี้:
foo = bar or 0
foo2 = bar or ""
ฉันใช้ int (x หรือ 0) สำหรับข้อผิดพลาดประเภทนี้สำเร็จแล้วตราบใดที่ None ควรเท่ากับ 0 ในตรรกะ โปรดทราบว่าสิ่งนี้จะแก้ไขเป็น 0 ด้วยในกรณีอื่น ๆ ที่การทดสอบ x ส่งคืน False เช่นรายการว่างชุดพจนานุกรมหรือสตริงความยาวเป็นศูนย์ ขออภัย Kindall ได้ให้คำตอบนี้แล้ว
สิ่งนี้สามารถเกิดขึ้นได้หากคุณลืมส่งคืนค่าจากฟังก์ชันจากนั้นจะส่งคืนค่า None ดูตำแหน่งทั้งหมดที่คุณกำหนดให้กับตัวแปรนั้นและดูว่าหนึ่งในนั้นเป็นการเรียกใช้ฟังก์ชันโดยที่ฟังก์ชันไม่มีคำสั่ง return หรือไม่
return return some_expression
return Noneคำสั่งอย่างน้อยหนึ่งรายการ
คุณควรตรวจสอบให้แน่ใจว่าค่าไม่ใช่ None ก่อนที่จะพยายามทำการคำนวณใด ๆ :
my_value = None
if my_value is not None:
print int(my_value) / 2
หมายเหตุ: my_valueถูกตั้งค่าโดยเจตนาเป็นไม่มีเพื่อพิสูจน์ว่ารหัสใช้งานได้และกำลังดำเนินการตรวจสอบ
is [not] None)
my_valueไม่มีโดยไม่มีเงื่อนไข ทำไม? คุณไม่ต้องสงสัยว่าทำไม OP ถึงคิดว่าเขาต้องทำint(my_value)เมื่อmy_valueคือ (ถ้าไม่ใช่ไม่มี)
ฉันประสบปัญหาเดียวกันกับการใช้ฟังก์ชันอีเมล 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()
ในบางสถานการณ์การมีฟังก์ชันในการแปลง None เป็น int zero จะเป็นประโยชน์:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value