【问题标题】:How to convert Nonetype to int or string?如何将 Nonetype 转换为 int 或 string?
【发布时间】:2011-04-25 05:12:47
【问题描述】:

我有一个Nonetypex,它通常是一个数字,但也可以是None。我想将它除以一个数字,但 Python 会引发:

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

我该如何解决这个问题?

【问题讨论】:

  • 假设 None 等于 2771。但也许这不是你想要的。请提供更多信息。
  • 不知何故我得到了一个N​​onetype值,它应该是一个int,但它现在是一个Nonetype对象,我需要除以另一个数字,然后错误出现了。
  • int(None) 抛出异常,因为 None 无法转换为 int。您的问题的答案是无法完成。您可以替换一些东西,例如 0、2771 或粉红色的大象,但无论您替换什么,您仍然无法将 None 转换为 int。
  • @ma3204。将None 转换为粉红色的大象也不好,除非您正在使用某种数字系统来正式定义一个数字除以粉红色的大象(并且您已经编写了支持它的代码)

标签: python


【解决方案1】:
int(value or 0)

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

int(0 if value is None else value)

这仅将 None 替换为 0。由于我们正在专门测试 None,因此您可以使用其他值作为替换。

【讨论】:

  • user469652 您应该考虑将此作为接受的答案。这实际上是有帮助的,而不是居高临下
  • 我不确定这是否能解决用户面临的问题,即。使用 nonetype 执行计算...我目前正在通过 rest api 提取数据,该 api 返回包含数值的 nonetype。如果我将其设置为 0 或保持原样,我将无能为力
  • 这绝对是最好的答案,给定这个问题,因为用户指出 None 应该是预期的,就像可能是一个函数一样,请求返回 None 的东西的值以表明该值是未知的如果 None 应该成为其用例中的默​​认值,通常为 0。考虑 izip_longest,默认参数,如果不同的参数具有不同的默认值(偶数类型),那么默认值应该是 None,然后替换为默认值,但是 string.(str, w) 只需要一个整数作为宽度。
  • 这很有帮助,整洁又聪明
  • 我们可以使用 (value or 0) -- 没有 int 类型转换 -- 如果我们保证 value 只能是 None 或 int
【解决方案2】:

在其中一个 cmets 中,你说:

不知何故,我得到了一个 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(如果它存在的话)完全取决于您的代码的用途。

【讨论】:

  • +1 表示“正确”的解决方案。如果您的窗户经常神秘地破裂,请找出原因(并抓住负责的破坏者)而不是堵住窗户;)
  • 这在您从 redis 字典中检索键的情况下没有用,例如,因为缺少的键将为无。如果你想对它们求和而不考虑它们的存在(这是完全可以接受的行为),你可能需要将 None 转换为 0 (见 kindall answer)
  • @spider - 这仍然意味着它高度依赖于情况,并且“确定一个合理的值”仍然适用。
  • Spider 的观点非常有效这个答案基本上只是说你做错了什么,但 None 并不意味着它意味着未知值,这可能表明你做错了什么,或者蜘蛛建议一个缺失值,一般来说,它应该是 0 或可能是 1,对于 None 的大多数可能用途,其中需要一个整数。
  • @glenflet 如果您不知道函数的输入域和规范是什么,互联网上的陌生人将无法告诉您。如果您知道,但不知道转换它的语法,那么这与这里提出的问题完全不同。
【解决方案3】:

处理这种情况的常见“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 jump”,这是@Soviut 和其他一些人所建议的。有关该主题的更多报道,请参阅我的 answer 以及本网站其他地方的问题 Determine whether a key is present in a dictionary 的相关 cmets。

EAFP 的一个潜在问题是它可以隐藏代码的其他部分或您正在使用的第三方模块有问题的事实,尤其是当异常频繁发生时(因此根本不是真正的“例外”情况)。

【讨论】:

    【解决方案4】:

    TypeError 仅在您尝试传递 int() None 时出现(据我所知,这是唯一的 NoneType 值)。我想说你的真正目标不应该是将NoneType 转换为intstr,而是要弄清楚你在哪里/为什么得到None 而不是预期的数字,然后修复它或正确处理None

    【讨论】:

      【解决方案5】:

      在 Python 3 中,您也可以使用“或”关键字。这样:

      foo = bar or 0
      foo2 = bar or ""
      

      【讨论】:

      • 就是这样。这是正确的解决方案!
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        如果您忘记从函数返回值,就会发生这种情况:然后它返回 None。查看您分配给该变量的所有位置,并查看其中一个是否是函数调用,其中该函数缺少返回语句。

        【讨论】:

        • ... 或者该函数有一个或多个返回语句,它们只是普通的return 而不是return some_expression
        • ...或者函数包含一个或多个return None语句
        【解决方案8】:

        在尝试对其执行任何计算之前,您应该检查以确保该值不是无:

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

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

        【讨论】:

        • 你应该使用身份比较(is [not] None
        • -4 你应该鼓励 OP 找出他真正的问题是什么,而不是避免它。 @shylent 说了什么。您将my_value 无条件设置为无;为什么?你不会质疑为什么当my_value 是(如果不是无)“通常是一个数字”时,OP 认为他需要做int(my_value)
        • 我将 my_value 设置为 None 作为概念证明,以表明我的代码不会失败。我没有质疑 OP,因为有很多原因导致一个值可能并不总是一个数字,并且在执行计算之前检查它是一个好主意。简单地回答OP的问题没有错,我不必为他们做所有的功课。
        【解决方案9】:

        我在使用 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()
        

        【讨论】:

          【解决方案10】:

          在某些情况下,有一个将 None 转换为 int 零的函数会很有帮助:

          def nz(value):
          
              '''
              Convert None to int zero else return value.
              '''
          
              if value == None:
                  return 0
              return value
          

          【讨论】:

            猜你喜欢
            • 2019-12-11
            • 2010-11-04
            • 2012-11-22
            • 2011-05-29
            • 2011-11-19
            • 2011-12-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-28
            相关资源
            最近更新 更多