关于python:如何将Nonetype转换为int或string?

How to convert Nonetype to int or string?

我有一个Nonetypex,通常是一个数字,但可以是None。我想把它除以一个数字,但python提出:

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

我怎么解决这个问题?


1
int(value or 0)

如果您提供了python认为False的任何值,例如none、0、[]"等,则将使用0。由于0是False,因此您只应使用0作为可选值(否则,您将发现0正在转换为该值)。

1
int(0 if value is None else value)

这只将None替换为0。因为我们专门测试None,所以您可以使用其他值作为替换。


在其中一条评论中,你说:

Somehow I got an Nonetype value, it supposed to be an int, but it's now a Nonetype object

如果这是你的代码,当你期望一个数字的时候,弄清楚你是如何得到None,并阻止它的发生。

如果是别人的代码,找出它给None的条件,并用通常的条件代码确定一个合理的值:

1
2
3
4
result = could_return_none(x)

if result is None:
    result = DEFAULT_VALUE

…甚至…

1
2
3
4
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(如果它甚至存在)完全取决于代码的用途。


处理这种情况的一种常见的"Python式"方法被称为EAFP,因为"请求宽恕比请求允许更容易"。这通常意味着编写假定一切正常的代码,然后用try..except块包装它,以防在不正常的情况下处理问题。

下面是应用于您的问题的编码样式:

1
2
3
4
5
6
try:
    my_value = int(my_value)
except TypeError:
    my_value = 0  # or whatever you want to do

answer = my_value / divisor

或者更简单、更快:

1
2
3
4
try:
    answer = int(my_value) / divisor
except TypeError:
    answer = 0

相反的,更传统的方法被称为lbyl,它代表"三思而后行",这是@soviut和其他一些人提出的建议。有关此主题的更多内容,请参阅我对该问题的回答和相关评论,以确定此网站其他地方的词典中是否存在密钥。

EAFP的一个潜在问题是,它可以隐藏这样一个事实,即您正在使用的代码或第三方模块的某些其他部分有问题,特别是在异常频繁发生时(因此根本不是"异常"情况)。


只有当你试图通过int()None时,TypeError才出现(据我所知,这是唯一的NoneType值)。我想说的是,你的真正目标不应该是把NoneType转换成intstr,而是弄清楚你从哪里/为什么得到None,而不是像预期的那样得到一个数字,然后修复它或正确地处理None


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


在python 3中,也可以使用"or"关键字。这种方式:

1
2
foo = bar or 0
foo2 = bar or""


我在使用python电子邮件功能时遇到了同样的问题。下面是我试图将电子邮件主题检索到变量中的代码。这对大多数电子邮件都很有效,并且变量也很常见。如果您收到来自雅虎或类似公司的电子邮件,而发件人没有填写主题行,雅虎不会在电子邮件中创建主题行,并且您会从函数中得到一个非类型的返回。马蒂诺提供了一个正确的答案,同时也提供了苏维埃。从编程的角度来看,imo soviut的答案更简洁;不一定是从Python的角度来看。下面是一些代码来演示该技术:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
2
3
my_value = None
if my_value is not None:
    print int(my_value) / 2

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


在某些情况下,使用函数将none转换为int zero很有帮助:

1
2
3
4
5
6
7
8
9
def nz(value):

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


    if value == None:
        return 0
    return value