【问题标题】:Why am I getting an error message in Python 'cannot import name NoneType'?为什么我在 Python 中收到错误消息“无法导入名称 NoneType”?
【发布时间】:2013-03-28 12:07:29
【问题描述】:

我正在尝试将一些代码从 2 转换为 3 以及以下简单脚本

import types
from types import NoneType

结果

ImportError: 无法导入名称 NoneType

如何将上面的从 2 转换为 3?

【问题讨论】:

  • 因为NoneType 只有一个实例,所以x is None 完全等于isinstance(x, NoneType)。如果您根据 None 检查类型,则有问题。
  • @GarethLatty 对于元组用例很有用。 isinstance(json_compatible_basic_type_expected, (int, float, str, NoneType))

标签: python python-3.x porting


【解决方案1】:

types 模块中不再有 NoneType 引用。您应该直接使用None 检查身份,即obj is None。如果您真的需要NoneType,另一种方法是使用它:

NoneType = type(None)

这实际上与之前定义 types.NoneType 的方式完全相同,在 November 28th, 2007 上被删除之前。

附带说明,您无需导入模块即可使用from .. import 语法,因此如果您不在其他任何地方使用模块引用,则可以删除import types 行。

【讨论】:

    【解决方案2】:

    如果您的用例允许,您可以:

    if my_dict.get('key'):  # By Default: returns None if key doesn't exists
        # Do something
    else:
        # Do something with None
    

    None 是一个虚假值,因此您无需导入任何内容即可使用 if-else 语句。

    【讨论】:

      【解决方案3】:

      在执行验证时获取NoneType 很有用,可以缩短通过可接受类型元组中允许的None 类型的条件链。所以不要写这样的东西:

      a = {...}
      is_valid = (
          a.get(mandatory_field) is None
          or isinstance(a[mandatory_field], str)
      )
      

      可以写:

      is_valid = isinstance(a.get(mandatory_field), (str, NoneType))
      

      可以通过将默认字符串值传递给.get(...) 来解决此问题(因为在没有该字段的情况下,您将返回有意通过验证的内容,即使该值不存在),但它太老套、晦涩难懂,而且确实影响可读性。

      由于NoneType 不再是您可以导入的东西,您可以在需要时自己制作。这些是一些选项:

      NoneType = type(None)
      NoneType = None.__class__
      

      如果您遵循 PEP8 建议,linter 可能会抱怨名为 NoneType 的变量不符合您的命名约定。我发现在需要NoneType 的地方使用type(None) 会更容易。这只是两个字符的区别,就像可读性一样,并且您节省了一行代码;)

      上述 sn-p 的最终解决方案如下所示:

      is_valid = isinstance(a.get(mandatory_field), (str, type(None)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多