问题:如何将Nonetype转换为int或字符串?
我有一个Nonetype
值x
,通常是一个数字,但可能是None
。我想将其除以数字,但是Python提出了:
TypeError: int() argument must be a string or a number, not 'NoneType'
我该如何解决?
I’ve got an Nonetype
value x
, it’s generally a number, but could be None
. I want to divide it by a number, but Python raises:
TypeError: int() argument must be a string or a number, not 'NoneType'
How can I solve this?
回答 0
在其中一项评论中,您说:
不知何故,我得到了一个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
(如果存在的话)完全取决于你的代码的目的。
In one of the comments, you say:
Somehow I got an Nonetype value, it supposed to be an int, but it’s now a Nonetype object
If it’s your code, figure out how you’re getting None
when you expect a number and stop that from happening.
If it’s someone else’s code, find out the conditions under which it gives None
and determine a sensible value to use for that, with the usual conditional code:
result = could_return_none(x)
if result is None:
result = DEFAULT_VALUE
…or even…
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.
There’s no reason to automatically use 0
here — solutions that depend on the “false”-ness of None
assume you will want this. The DEFAULT_VALUE
(if it even exists) completely depends on your code’s purpose.
回答 1
int(value or 0)
如果您提供Python认为的任何值False
,例如None,0,[],“”等False
,则将使用0。由于0为,您仅应使用0作为替代值(否则您将找到0变成那个价值)。
int(0 if value is None else value)
仅替换None
为0。由于我们正在None
专门测试,因此您可以使用其他一些值作为替换值。
int(value or 0)
This will use 0 in the case when you provide any value that Python considers False
, such as None, 0, [], “”, etc. Since 0 is False
, you should only use 0 as the alternative value (otherwise you will find your 0s turning into that value).
int(0 if value is None else value)
This replaces only None
with 0. Since we are testing for None
specifically, you can use some other value as the replacement.
回答 2
一种常见的处理此类情况的“ Python式”方法称为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和其他一些建议的“跳前先看 ”。有关此主题的更多信息,请参见我的回答和对该问题的相关注释。确定此站点上其他地方的词典中是否存在键。
EAFP的一个潜在问题是,它可以掩盖您正在使用的代码或第三方模块的其他部分出了问题的事实,尤其是在经常发生异常的情况下(因此并非真正的“exceptions”情况)完全没有)。
A common “Pythonic” way to handle this kind of situation is known as EAFP for “It’s easier to ask forgiveness than permission“. Which usually means writing code that assumes everything is fine, but then wrapping it with a try...except
block to handle things—just in case—it’s not.
Here’s that coding style applied to your problem:
try:
my_value = int(my_value)
except TypeError:
my_value = 0 # or whatever you want to do
answer = my_value / divisor
Or perhaps the even simpler and slightly faster:
try:
answer = int(my_value) / divisor
except TypeError:
answer = 0
The inverse and more traditional approach is known as LBYL which stands for “Look before you leap” is what @Soviut and some of the others have suggested. For additional coverage of this topic see my answer and associated comments to the question Determine whether a key is present in a dictionary elsewhere on this site.
One potential problem with EAFP is that it can hide the fact that something is wrong with some other part of your code or third-party module you’re using, especially when the exceptions frequently occur (and therefore aren’t really “exceptional” cases at all).
回答 3
这TypeError
仅当您尝试通过出现int()
None
(这是唯一的NoneType
价值,因为据我所知)。我要说的是,您的真正目标不应该是转换NoneType
为int
或str
,而是要弄清楚您要从何处/为什么获得None
该数字,而不是按预期的数字,然后对其进行修复或None
正确处理。
That TypeError
only appears when you try to pass int()
None
(which is the only NoneType
value, as far as I know). I would say that your real goal should not be to convert NoneType
to int
or str
, but to figure out where/why you’re getting None
instead of a number as expected, and either fix it or handle the None
properly.
回答 4
在Python 3中,您也可以使用“或”关键字。这条路:
foo = bar or 0
foo2 = bar or ""
In Python 3 you can use the “or” keyword too. This way:
foo = bar or 0
foo2 = bar or ""
回答 5
我已经成功地将int(x或0)用于这种类型的错误,只要逻辑中None应该等于0。请注意,在测试x返回False的其他情况下,这也将解析为0。例如,空列表,集合,字典或零长度字符串。抱歉,金德尔已经给出了这个答案。
I’ve successfully used int(x or 0) for this type of error, so long as None should equate to 0 in the logic.
Note that this will also resolve to 0 in other cases where testing x returns False. e.g. empty list, set, dictionary or zero length string.
Sorry, Kindall already gave this answer.
回答 6
如果您忘记从函数返回值,则会发生这种情况:然后返回None。查看分配给该变量的所有位置,并查看其中是否有一个函数调用缺少函数return语句。
This can happen if you forget to return a value from a function: it then returns None. Look at all places where you are assigning to that variable, and see if one of them is a function call where the function lacks a return statement.
回答 7
在尝试对其进行任何计算之前,应检查并确保该值不为 None:
my_value = None
if my_value is not None:
print int(my_value) / 2
注意: my_value
故意将其设置为“无”以证明代码有效并且正在执行检查。
You should check to make sure the value is not None before trying to perform any calculations on it:
my_value = None
if my_value is not None:
print int(my_value) / 2
Note: my_value
was intentionally set to None to prove the code works and that the check is being performed.
回答 8
我在使用python电子邮件功能时遇到了同样的问题。下面是我试图将电子邮件主题检索到变量中的代码。这对于大多数电子邮件都可以正常工作,并且会填充变量。如果您收到来自Yahoo等的电子邮件,但发件人没有填写主题行,Yahoo不会在电子邮件中创建主题行,并且您会从函数中返回NoneType。Martineau和Soviut都提供了正确的答案。从编程的角度来看,IMO 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()
I was having the same problem using the python email functions.
Below is the code I was trying to retrieve email subject into a variable. This works fine for most emails and the variable populates. If you receive an email from Yahoo or the like and the sender did no fill out the subject line Yahoo does not create a subject line in the email and you get a NoneType returned from the function. Martineau provided a correct answer as well as Soviut. IMO Soviut’s answer is more concise from a programming stand point; not necessarily from a Python one.
Here is some code to show the technique:
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()
回答 9
在某些情况下,具有将None转换为int零的函数会很有帮助:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value
In some situations it is helpful to have a function to convert None to int zero:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value