如何将Nonetype转换为整数或字符串?

140

我有一个Nonetype值的x,通常它是一个数字,但也可能是None。我想将其除以一个数字,但Python会报错:

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

我该怎么解决这个问题?


7
假设 None 等同于 2771。但也许这不是您想要的。请提供更多信息。 - JoshD
我得到了一个NoneType值,它应该是一个int类型,但现在它是一个NoneType对象,我需要除以另一个数字,然后就出现了错误。 - user469652
int(None) 抛出异常,因为 None 无法转换为 int。你的问题的答案是它无法完成。你可以替换成其他东西,比如0、2771或者粉色大象,但无论你替换成什么,你仍然无法将 None 转换为 int。 - snapshoe
8
将“None”转化为粉色大象也不好,除非你正在使用一种正式定义了数字可以被粉色大象整除的数字系统(并且你已经编写了支持此操作的代码)。 - aaronasterling
我正在使用pyudev,并返回一个值,当打印时看起来像“12d4”,它对应于USB VID。然而,type(value)是NoneType。一个有值的变量怎么可能是NoneType?当我尝试在该值上执行int()时,我得到与上述相同的错误。 - Brian Reinhold
10个回答

428
int(value or 0)

如果你提供Python认为是False的任何值,比如None、0、[]、""等,这将使用0。由于0是False,因此你应该只使用0作为替代值(否则你会发现你的0变成了那个值)。

int(0 if value is None else value)

这样只会将None替换为0。由于我们特别测试了None,所以您可以使用其他值作为替换。


89
您应该考虑将这个答案设为最佳答案,它确实有帮助,而不是轻视的。 - galarant
1
我不确定这是否解决了用户所面临的问题,即使用NoneType执行计算...我目前通过REST API获取数据,该API返回包含数字值的NoneType。如果我将其设置为0或保留原样,则无法对其进行任何操作。 - br3w5
2
这绝对是最好的答案,考虑到问题,因为用户指出应该期望None,就像可能是一个函数,请求某个值的返回值为None来表示该值未知,在这种情况下,None应该成为其使用情况中的默认值,通常为0。考虑izip_longest、默认参数,如果不同的参数有不同的默认值(甚至类型),那么默认值应该是None,然后替换为默认值,但是string.<align_n>(str,w)只接受整数作为宽度。 - Glen Fletcher
这非常有帮助,整洁而聪明。 - Anupam
2
如果我们确信value只能是None或int类型,那么我们可以使用(value or 0) -- 不需要进行int类型转换。 - hashlash
这真是太棒了!我需要将一堆字符串转换为浮点数,这对我的应用程序非常有效。 - Kyle

57
在其中一条评论中,您说:

某种方式我得到了一个NoneType值,它应该是一个整数,但现在它是一个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(如果它真的存在)完全取决于您代码的目的。


7
对于“正确”的解决方案给予加1。如果你的窗户经常神秘地破裂,找出原因(并抓住负责破坏的人),而不是封死窗户 ;) - user395760
4
如果你从 Redis 字典中检索键,这并不适用,因为缺少的键将是 None。如果你想总结它们而不考虑它们的存在(这是完全可以接受的行为),你可能需要将 None 转换为 0(参见 kindall 的答案)。 - spider
1
@spider - 这仍然意味着它高度依赖于情况,并且“确定合理的值”仍然适用。 - detly
蜘蛛的观点非常有道理,这个答案基本上只是说你做错了什么,但None并不意味着“错”,它表示未知值,这可能表明你做错了什么,或者像蜘蛛建议的那样,缺少某个值,在大多数情况下,当期望整数时,应该变成0或可能是1,以便最可能使用None。 - Glen Fletcher
@glenflet 如果你不知道你的函数的输入域和规范是什么,那么一个陌生的网友也无法告诉你。如果你知道,但不知道如何转换语法,那就是一个完全不同的问题,与此处所问的问题无关。 - detly

19

处理这种情况的一个常见的“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,意为“先看后跳”,这是@Soviut和其他一些人建议的方法。有关此主题的其他内容,请参阅我的答案以及与本网站其他位置的Determine whether a key is present in a dictionary问题相关的评论。

EAFP的一个潜在问题是它可能隐藏了代码的其他部分或您使用的第三方模块出现了问题,特别是当异常经常发生时(因此根本不是“异常”情况)。


14
在Python 3中,您也可以使用“or”关键字。用法如下:
foo = bar or 0
foo2 = bar or ""

1
这就是它。这是正确的解决方案! - Ulf Aslak
如果0是“bar”的有效值,那么这种方法将行不通,因为它也会被视为False。在这种情况下,“foo2”将变成一个空字符串,而不是整数0。 - bavaza

12

TypeError 只会在你试图将 int() 转换一个值为 None 的对象时(据我所知,None 是唯一的 NoneType 值),才会出现该错误。我认为你真正的目标不应该是将 NoneType 转换为 intstr,而是要找出为什么会得到 None,以及在哪里/为什么会得到它,然后修复它或正确处理掉 None


3

我曾经成功地使用int(x or 0)解决这种类型的错误,只要在逻辑上None应该等于0。 请注意,在其他情况下测试x返回False时,这也将解析为0。例如,空列表、集合、字典或零长度字符串。 抱歉,Kindall已经给出了这个答案。


1
我在使用Python的电子邮件功能时遇到了同样的问题。 以下是我尝试将电子邮件主题检索到变量中的代码。对于大多数电子邮件,这很好用并且变量被填充。如果您从Yahoo或类似的电子邮件中收到了未填写主题行的电子邮件,则Yahoo不会在电子邮件中创建主题行,并且您将从函数返回NoneType。Martineau提供了正确的答案,Soviut也提供了正确的答案。从编程角度来看,我认为Soviut的答案更加简洁;但不一定是从Python角度来看。 以下是一些代码以展示该技术:
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:
my_value = None
if my_value is not None:
    print int(my_value) / 2

注意: my_value 故意设置为 None,以证明代码有效,并且检查正在执行。


1
你应该使用身份比较(is [not] None)。 - shylent
-4 你应该鼓励原帖作者找出他真正的问题,而不是回避它。就像@shylent所说的那样。你无条件地将my_value设置为None;为什么?当my_value(如果不是None)“通常是一个数字”时,你不会质疑原帖作者为什么需要执行int(my_value) - John Machin
1
我将my_value设置为None,以证明我的代码不会失败。我没有质疑OP,因为一个值不总是数字的原因有很多,检查它是否为数字再进行计算是一个好主意。简单回答OP的问题并没有错,我不必替他们完成所有的作业。 - Soviut

1
这可能是因为您忘记从函数中返回值而发生的:它会返回 None。查看所有分配给该变量的位置,并查看其中是否有一个是函数调用,其中该函数缺少返回语句。

1
或者该函数有一个或多个返回语句,这些语句只是简单的“return”,而不是“return some_expression”。 - John Machin
...或者该函数包含一个或多个return None语句 - John Machin

1

在某些情况下,拥有一个将None转换为整数零的函数是有帮助的:

def nz(value):

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

    if value == None:
        return 0
    return value

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接